删除链表中重复的节点——重复节点保留一个

本文介绍两种删除排序链表中重复节点的算法,一种使用哈希集合实现,时间复杂度O(n),空间复杂度O(n);另一种通过遍历比较,时间复杂度O(n^2),空间复杂度O(1)。

题目:

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点保留一个,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->3->4->5

代码1:时间复杂度O(n),空间复杂度O(n)

ListNode* remove(ListNode* head)
{
    if (head == nullptr || head->next == nullptr)
        return head;
    unordered_set<int> s;
    s.insert(head->val);
    ListNode* pre = head;
    ListNode* cur = head->next;
    while (cur != nullptr)
    {
        if (s.count(cur->val))
        {
            pre->next = cur->next;
            cur = cur->next;
        }
        else
        {
            s.insert(cur->val);
            pre = pre->next;
            cur = cur->next;
        }
    }
    return head;
}

代码2:时间复杂度O(n^2),空间复杂度O(1)

ListNode* remove(ListNode* head)
{
    if (head == nullptr || head->next == nullptr)
        return head;
    ListNode* cur = head;
    while (cur != nullptr)
    {
        ListNode* pre = cur;
        ListNode* next = cur->next;
        while (next != nullptr)
        {
            if (cur->val == next->val)
            {
                next = next->next;
                pre->next = next;
            }
            else
            {
                pre = next;
                next = next->next;
            }
        }
        cur = cur->next;
    }
    return head;
}

参考资料:

左程云著《程序员代码面试指南》

### 线性链表删除重复节点算法 对于线性链表删除重复节点的操作,可以采用线性扫描的方法,在遍历过程中移除那些已经出现过的节点。为了简化边界条件的处理,通常会引入一个虚拟头结点(哨兵),不过这里直接基于原始链表来展示逻辑以便于理解[^1]。 具体来说,当遇到第一个重复项时保留它,而之后相同数的所有实例都将被跳过不加入到最终的结果列表里。此过程仅需一次完整的单向遍历即可完成,时间复杂度为O(n)[^2]。 下面是Python版本的具体实现: ```python class ListNode: def __init__(self, value=0, next=None): self.value = value self.next = next def remove_duplicates(head: ListNode) -> ListNode: current = head while current and current.next: if current.value == current.next.value: current.next = current.next.next # 跳过下一个具有相同节点 else: current = current.next return head ``` 上述函数`remove_duplicates`接收指向链表头部的一个指针作为参数,并返回经过清理后的链表新头部位置。通过迭代的方式检查相邻两个元素是否相等;如果发现连续相同的元素,则调整前驱节点的next指向前继节点而不是当前应该被去除掉的那个重复节点。 需要注意的是,这段代码只会移除紧挨着彼此的重复条目——即只留下每组重复数中的首个出现者。对于非邻接式的重复情况则不会受到影响。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值