剑指offer55--链表中环的入口结点

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

思路

思路1:有环意味着遍历的时候在一定的时间之后,会出现重复的指针。因此我们可以用一个map来存储出现的次数,一旦发现某个结点已经出现过了,即次数大于了1,立即输出;否则等遍历到底就说明是没有环的。

实现:

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        map<ListNode*,int> m;
        //unordered_map<ListNode*,int> m;
        //用unordered_map性能会更好,在插入和查找的复杂度都比map低,并且空间复杂度也比map低
        while (pHead)
        {
            m[pHead]++;
            if (m[pHead]>1) return pHead;
            pHead=pHead->next;
        }
        return nullptr;
    }
};

用set会获得更好的效果,因为set只有关键字而没有关键字的值,相当于省了一半的空间

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        unordered_set<ListNode*> s;
        while (pHead)
        {
            if (s.find(pHead)==s.end())//这里的find返回的是一个迭代器,如果迭代器指向了set的末尾,说明没有找到pHead,接下来就插入和后移。
            {
                s.insert(pHead);
                pHead=pHead->next;
            }
            else
                return pHead;
        }
        return nullptr;
    }
};

关于set和unordered_set的知识:
C++中set和unordered容器的使用

思路2:双指针法(快慢指针)
具体操作:
1.初始化两根指针fast和slow指向链表头结点
2.快指针每次走2步,慢指针每次走1步,当第一次相遇时停下来
3.再让快指针回到起点,慢指针不动,一起每次走一步,再次相遇即入口结点

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        ListNode* fast=pHead;
        ListNode* slow=pHead;
        while (fast&&fast->next)
        {
            fast=fast->next->next;
            slow=slow->next;
            if (slow==fast) break;//第一次相遇
        }
        if (!fast||!fast->next) return nullptr;//检查上面的while退出是因为fast或者fast->next为空退出(即没有环)还是因为fast和slow指针相遇退出的
        
        fast=pHead;//将快指针重新指向头结点
        while (fast!=slow)
        {
            fast=fast->next;//一起每次走一步
            slow=slow->next;
        }
        return fast;
    }
};

具体分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值