LC.82 | 删除排序链表中的重复元素 II | 链表 | 三指针

输入: 一个已排序的单链表的头节点 head

要求: 删除原始链表中所有具有重复数字的节点,只留下不同的数字。返回已排序的链表。

输出: 删除所有重复项后,已排序的链表头节点。


思路:虚拟头节点 + 三指针

这道题的关键在于,一个节点是否应该被保留,取决于它的后一个节点的值是否与它相同。使用虚拟头节点 dummy 来统一处理头节点可能被删除的情况。

  • 定义三个指针:nodea 作为结果链表的尾指针,初始指向 dummynodeb 作为当前待考察的节点;nodec 作为nodeb的下一个节点,用于判断 nodeb 是否重复。

  • 循环以 nodeb 是否存在为条件。在循环中,判断 nodeb 是否是一个独特的节点。

  • 如果 nodeb 的下一个节点 nodec 不存在,或者 nodec 的值与 nodeb 不同,说明 nodeb 是一个独特的节点,应该被保留。此时,将 nodea 连接到 nodeb,然后 nodeanodeb 一同前进。

  • 如果 nodeb 的下一个节点 nodec 的值与 nodeb 相同,说明 nodeb 是一个重复节点,必须被删除。此时 nodea 保持不动,我们用一个内部循环跳过所有与 nodeb 值相同的节点,然后将 nodeb 直接指向下一个不同的节点,进入下一轮考察。

复杂度:

  • 时间复杂度: O(n)

  • 空间复杂度: O(1)


class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode* dummy = new ListNode(-1, head);
        ListNode* nodea;//每一轮开始的起点 自身是绝对安全的
        ListNode* nodeb;//待考察点 需要考察后续的点是否跟本点相同 
        ListNode* nodec;//前哨点 从待考察点出发 到 空节点之前或者下一个待考察点之前
        nodea = dummy;//很安全
        nodeb = dummy->next;
        while (nodeb) { //如果待考察点依旧存在就继续考察 如果不存在了 那确实该结束了
            nodec = nodeb->next;//开始对nodeb考察
            if (!nodec || nodec->val != nodeb->val) {//考察成功 要么后面没有 要么不等
                nodea->next = nodeb;
                nodea = nodeb;
                nodeb = nodec;
            }
            else {
                while (nodec->next && nodec->next->val == nodeb->val) {
                    nodec = nodec->next;
                }
                if (!nodec->next) {
                    nodea->next = nullptr;
                    nodeb = nullptr;
                }
                else {
                    nodeb = nodec->next;
                }
            }
        }
        return dummy->next;
    }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值