【程序员面试金典】面试题 02.01. 移除重复节点

【程序员面试金典】面试题 02.01. 移除重复节点

题目描述

描述:编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。

输入:[1, 2, 3, 3, 2, 1]
 输出:[1, 2, 3]
输入:[1, 1, 1, 1, 2]
 输出:[1, 2]

链表长度在[0, 20000]范围内。
链表元素在[0, 20000]范围内。

解题思路

思路1:最直观的想法是,创建一个头结点L,其指向链表的第一个结点head,然后为了删除方便,使用p指向当前结点的前一个结点,其初始化为L,再使用一个uset存储不重复的元素,当当前结点不为空,即p&&p->next,如果能在uset中找到当前结点值,则表示重复,于是删除当前结点,注意,此时只是改变p->next的指向,但是不改变p喔,反之如果不能在uset中找到当前结点值,则表示不重复,故将当前结点值插入uset,并且将p后移一位。

ListNode* removeDuplicateNodes(ListNode* head) 
{
    // 存储不重复的元素值
    unordered_set<int> uset;
    // 头结点
    ListNode* L=new ListNode(0);
    L->next=head;
    // 从头节点开始
    ListNode* p=L;
    // 为了方便 p指向当前节点的前一个节点 要求当前节点不为空
    while(p&&p->next!=NULL)
    {
       // 找到 出现重复
       if(uset.find(p->next->val)!=uset.end())
          p->next=p->next->next;
       // 没找到 插入
       else
       {
          uset.emplace(p->next->val);
          p=p->next;
       }
    }
    return L->next;
}

总结:以前我们处理的是在排序后的链表中删除重复元素,由于其重复元素都是连续出现的,所以我们没有使用额外的存储空间来存储非重复值,而是直接判断当前的下一个与当前的下下一个是否相等,如果相等则保存相等值来进行删除。现在我们处理的是在未排序的链表中删除重复元素,故我们需要使用uset来存储非重复值来帮助我们判断。但是,有一个共同点,为了方便删除,我们都会创建一个头结点,以及使用一个指针指向当前节点的前一个节点,即如果出现重复元素,则直接使用前一个节点来进行删除,注意,此时是不需要将前一个节点后移的,只有当前未出现重复才需要后移前一个节点。同时,当判断p->next不为空时,一定要先判断p不为空,否则会报错喔。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值