剑指Offer-23:链表中环的入口节点

题目:

如果一个链表中包含环,请找出该链表的环的入口结点。

例子

如:在1->2->3->4->5->6->3的链表中,包含一个环,环的入口节点是3。

链接:

剑指Offer(第2版):P139

思路标签:

  • 数据结构:链表
  • 算法:双指针

解答:

1. C++
  • 对问题进行分步解决。
  • (1) 确定链表中是否包含环:双指针,一个每次移动一步,一个每次移动两步,如果两个指针最后相遇,那么就包含环。(注意,移动两步的指针要判断判断其第一步不为空,才能移动第二步)
  • (2) 确定环中点节点数目:在上面相遇的节点的基础上,移动一个指针,并计数,当指针回到该节点时,确定环中节点数目。
  • (3) 找到环的入口节点:从头开始,使用两个指针,第一个指针先移动n步(其中n为确定的环中的节点数目),第二个指针再开始同时移动,两个指针相遇的节点即为入口节点。
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        ListNode* meetingNode = MeetingNode(pHead);
        if(meetingNode == nullptr) return nullptr;

        int nodesNumInLoop = 1;
        ListNode* pNode1 = meetingNode;
        while(pNode1->next != meetingNode){
            pNode1 = pNode1->next;
            ++nodesNumInLoop;
        }

        pNode1 = pHead;
        for(int i=0; i<nodesNumInLoop; ++i)
            pNode1 = pNode1->next;

        ListNode* pNode2 = pHead;
        while(pNode1 != pNode2){
            pNode1 = pNode1->next;
            pNode2 = pNode2->next;
        }
        return pNode1;
    }

    ListNode* MeetingNode(ListNode* pHead){
        if(pHead == nullptr) return nullptr;

        ListNode* pSlow = pHead->next;
        if(pSlow == nullptr) return nullptr;

        ListNode* pFast = pSlow->next;
        while(pSlow != nullptr && pFast != nullptr){
            if(pSlow == pFast) return pFast;

            pSlow = pSlow->next;
            pFast = pFast->next;
            if(pFast != nullptr)
                pFast = pFast->next;
        }
        return nullptr;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值