题目描述

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

思路:

1)首先利用快慢指针判断是否有环,如果无环则返回null,有环则进行下一步操作

2)如果有环,即可看作下图的示例,假设ABAB段即环外的长度为LLBPBP段即从进入环到交点的长度为xx,整个环的长度设为mm;假设慢指针在环中所走的圈数为tt,快指针所走的圈数为kk,那么慢指针所走的距离即为L+tm+xL+ tm + x,快指针所走的距离即为L+km+xL + km + x,因为快指针所走的距离为慢指针所走距离的两倍,所以有
L+km+x=2(L+tm+x)>L=(k2t)mx=(k2t1)m+mxL + km + x = 2(L + tm + x) -->L = (k - 2t)m - x = (k - 2t - 1)m + m - x
LL相当于从pp走到BB然后再走k2t1k - 2t - 1圈环,那么我们可以让慢指针从pp开始走LL段距离,那么其最后会在BB点即环入口,那么如何确定该LL的大小呢?
我们可以让一个指针从AA走到BB,这段距离即为LL,让慢指针与该指针一同出发,相等时即为环入口
【剑指offer】链表中环的入口结点

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        ListNode* pFast = pHead;
        ListNode* pSlow = pHead;
        while (pFast != nullptr && pFast->next != nullptr) {
            pFast = pFast->next->next;
            pSlow = pSlow->next;
            if (pFast == pSlow)
                break;
        }
        if (pFast == nullptr || pFast->next == nullptr)
            return nullptr;
        pFast = pHead;
        while (pFast != pSlow) {
            pFast = pFast->next;
            pSlow = pSlow->next;
        }
        return pFast;
    }
};

相关文章: