题目描述1
删除排序链表中的重复元素: 存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除所有重复的元素,使每个元素 只出现一次 。
返回同样按升序排列的结果链表。
输入: head = [1,1,2]
输出: [1,2]
解题思路
- 要删除重复元素,肯定需要作比较,那我们就需要两个指针pre=head,cur=head.next
- 我们这里不借助虚头,让头节点不被删除,如果遇到重复的删除后面的即可
- 如果遇到重复的,就让后面的cur指针继续向后走,直至遇到和pre.val不相等的节点
- 如果pre和cur不重复,那么直接让pre指向的节点连接cur指向的节点即可,即pre.next=cur
开始解题
var deleteDuplicates = function(head) {
if(!head) return null;
let pre = head, cur = head.next;
while(cur) {
if(pre.val === cur.val) {
cur = cur.next;
if(!cur) { // 如果最后几个都是重复元素,pre直接指向为null的cur即可
pre.next = cur;
}
}else {
pre.next = cur;
pre = cur; // 在比较过前两个不重复的元素之后,pre和cur分别向后移动1位,即可比较下一组的两个节点
cur = cur.next;
}
}
return head;
};
题目描述2
删除排序链表中的重复元素2: 存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。
返回同样按升序排列的结果链表。
输入: head = [1,1,2]
输出: [2]
扩展思路
- 相比删除单个重复元素来说,本道题目是删除所有重复元素
- 因为头节点可能重复会被删除,所以借助虚头
- 同样是借助两个指针,不过这里用法不一样,虚头指针pre和比较指针cur
- 每次比较cur和cur.next是否重复,那么如果重复这两个都会被删除,那么保持pre在cur的前一位,如果比较到不同的节点,pre指向cur即可,cur=cur.next,那么pre就变成了下组比较的前个节点了
- 同题1,如果最后如果干个重复节点,那么当cur为null时,pre.next = null即可
开始解题
var deleteDuplicates = function(head) {
if(!head) return null;
let ret = new ListNode(-1,head),pre=ret, cur = head;
while(cur && cur.next) {
if(cur.val !== cur.next.val) {
pre = cur; // 比较到不同的节点,pre指向cur即可
cur = cur.next; // 此时pre就变成了下组比较的前个节点了
}else {
while(cur && cur.next && cur.val === cur.next.val) {
cur = cur.next;
} // 找到不重复节点cur.next
pre.next = cur.next; // pre连接到不重复节点,这里pre指针无需移动,因为不重复节点是下组节点的比较起点
cur = cur.next;
if(!cur) {
pre.next = cur;
}
}
}
return ret.next;
};