Remove Duplicates from Sorted List(去除有序链表中的重复元素)

本文探讨了如何从有序链表中删除重复元素,提出了两种不同的解决方案,并对比了它们的优劣。一种方法是在原链表基础上直接删除重复项,另一种方法是创建新链表并仅复制唯一值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a sorted linked list, delete all duplicates such that each element appear only once.(给定一个有序链表,删除所有的重复元素,使得所有元素都是唯一的)

For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.

1.个人分析
之前遇到过类似的问题,只不过这里给出的是有序链表,而且也没有要求只能在原序列中操作,所以就不用自己去先排序,这里可以使用一个额外的链表来保存最终结果,或者双指针的方法进行处理。
思路:
(1)设立两个指针p1,p2,用p1始终指向新链表的尾部节点,而p2用来遍历p1之后的所有节点
(2)如果p2指向的节点与p1指向的节点不同,则将p2指向的元素复制到p1的后一个位置,然后将p1后移一位,否则p2就继续往后遍历,直到遍历完成。
(3)使p1->next=NULL,释放p1之后所有节点的空间。

2.个人解法
(1)覆盖之后再删除

ListNode* deleteDuplicates(ListNode* head)
{
    if(!head || head->next == NULL)
        return head;
    ListNode *p1, *p2;
    p1 = head;
    p2 = p1->next;

    while(p2)
    {
        if(p1->val != p2->val){
            p1->next->val = p2->val;
            p1 = p1->next;
        }else{
            p2 = p2->next;
        }
    }

    p2 = p1->next;
    p1->next = NULL;
    ListNode *tmp = NULL;
    while(p2)
    {
        tmp = p2;
        p2 = p2->next;
        delete tmp;
    }

    return head;
}

(2)边修改指针边删除

ListNode* deleteDuplicates(ListNode* head)
{
    if(!head || head->next == NULL)
        return head;
    ListNode *p1, *p2, *tmp;
    p1 = head;
    p2 = p1->next;

    while(p2)
    {
        if(p1->val == p2->val){             
            p1->next = p2->next;
            tmp = p2;
            delete tmp;
        }else{
            p1 = p2;
        }
        p2 = p2->next;          
    }   

    return head;
}

3.参考解法

public ListNode deleteDuplicates(ListNode head) {
    ListNode current = head;
    while (current != null && current.next != null) {
        if (current.next.val == current.val) {
            current.next = current.next.next;
        } else {
            current = current.next;
        }
    }
    return head;
}

该解法是Java实现的,思想是从头到尾遍历一次有序链表,如果两相邻节点值相同,就将当前节点的next指向下下个节点,当遍历结束时,链表中也就不含重复的节点了。这种解法是利用了有序的特性,否则就无法使用该法来解决。

4.总结
个人解法中的第一种解法是来源于从一个数组中去除重复元素,采用双指针方法,但该方法需要在最后删除新链表之后的节点,所以效率上会比第二种方法低一些。另外自己在LeetCode中尝试了一下不进行手动delete操作,虽然也能AC,但这样在实际中极有可能造成内存泄露的。

PS:

  • 题目的中文翻译是本人所作,如有偏差敬请指正。
  • 其中的“个人分析”和“个人解法”均是本人最初的想法和做法,不一定是对的,只是作为一个对照和记录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值