力扣面试150(52/150)
8.10 82. 删除排序链表中的重复元素 II
给定一个已排序的链表的头 head
, 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
我的思路:
最开始时想到的set,但是我发现并不是删除重复的让它不重复,而是删除全部重复的数字,这样的话用set就不现实了,因为无论如何都会保留下来一个的。所以我又想到了另外一个方法,使用自带的next指针,但是使用这个的话就要创建一个虚拟头节点,还要考虑很多边界问题。
大概的思路就是:如果carry.next.val === carry.next.next.val => 保存这个val然后进行遍历啊,一直到carry.next.val!==val的时候,在循环当中要做的就是修改carry的next指针
我的代码:
var deleteDuplicates = function(head) {// 新建虚拟链表let dummy = new ListNode();dummy.next = head;let carry = dummy;while(carry&& carry.next && carry.next.next){if(carry.next.val === carry.next.next.val){const x = carry.next.val;while(carry.next && carry.next.val === x){carry.next = carry.next.next;}}else {carry = carry.next;}}return dummy.next;
};
这里有一个注意的点:如果是返回的head,如果是head = [1,1,1,2,3]的情况,你就删除了head,head指针失效,所以返回head是没有用的
我的总结:这段代码通过引入一个虚拟头节点 dummy
来巧妙地处理链表删除所有重复节点的问题。它让一个 carry
指针从 dummy
开始向后遍历,当 carry
后面的两个节点值相等时,就找到了一个重复组。此时,它会记录下这个重复值,并不断地将 carry
的 next
指针向后移动,直到跳过所有该值的节点,从而实现整组删除。如果后面两个节点值不相等,说明当前节点是唯一的,carry
指针就正常后移一位。最终,无论原始的 head
节点是否被删除,dummy.next
始终指向处理完毕后链表的真正头部,保证了算法在各种情况下的正确性。