82. 删除排序链表中的重复元素 II

82. 删除排序链表中的重复元素 II
是一个有序链表

错误代码

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode dummy = new ListNode();
        dummy.next = head;
        while(head != null && head.next != null) {
            if (head.val == head.next.val) {
                head.next = head.next.next;
            }
            head = head.next;
        }
        return dummy.next;
    }
}

这段代码的目的是删除单链表中的所有重复元素,但是它只能删除连续且相邻的重复元素,并且存在一个逻辑错误。错误在于当发现重复元素时,代码没有保持当前节点不变以继续检查后续是否还有重复元素,而是直接移动到了下一个节点。这会导致在一系列连续重复元素中,只删除了第一个重复元素后的一个元素,而不是删除所有重复的元素。

例如,对于链表 1 -> 2 -> 2 -> 3,按照这段代码的逻辑,处理后的链表将会是 1 -> 2 -> 3,这是正确的。但是,对于链表 1 -> 2 -> 2 -> 2 -> 3,处理后的链表将会是 1 -> 2 -> 2 -> 3,这是不正确的,因为它没有删除所有的重复元素。

为了修正这个问题,我们需要在发现重复元素时,不移动 head 指针,直到确保没有更多的重复元素。以下是修正后的代码:

public class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null) return null;
        
        ListNode dummy = new ListNode(0, head);
        ListNode cur = dummy;
        
        while (cur.next != null && cur.next.next != null) {
            if (cur.next.val == cur.next.next.val) {
                int dupVal = cur.next.val;
                while (cur.next != null && cur.next.val == dupVal) {
                    cur.next = cur.next.next; // 删除重复元素
                }
            } else {
                cur = cur.next; // 没有重复,移动到下一个节点
            }
        }
        
        return dummy.next;
    }
}

修正后的代码逻辑:

  1. 创建一个哑节点 dummy,其 next 指向 head,以简化边界条件处理。
  2. 使用 cur 指针遍历链表,初始时指向 dummy
  3. cur 的下一个节点和下下一个节点不为空时,检查这两个节点的值是否相等。
    • 如果相等,说明有重复元素。记录重复的值 dupVal,然后使用一个循环删除所有值为 dupVal 的节点。
    • 如果不相等,说明当前节点不重复,cur 指针移动到下一个节点。
  4. 返回 dummy.next,即新链表的头节点。
posted @ 2024-07-13 22:25  economies  阅读(89)  评论(0)    收藏  举报