链表中环的入口节点

1、用快慢指针从头节点开始,快指针一次走两步,慢指针一次走一步,若有环,必然会相遇。

2、将其中一个指针重置到头节点,另一个指针指向相遇节点,然后以相同速度走,再次相遇必然是环的入口节点

 

当相遇时:

然后将一个指针重置到头节点,另一个指针指向相遇节点,然后以相同速度走,再次相遇必然是环的入口节点:

代码:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
         ListNode* meetingNode = MeetingNodeOfLoop(pHead);
        if (meetingNode == nullptr)
            return nullptr;    //找到了链表中的环

        while (pHead != meetingNode){
            pHead = pHead->next;
            meetingNode = meetingNode->next;
        }
        return meetingNode;
    }
    
    //寻找环中相遇的节点
    ListNode* MeetingNodeOfLoop(ListNode* pHead)
    {
        if (pHead == nullptr || pHead->next == nullptr)
            return nullptr;
        ListNode *slow = pHead->next;
        ListNode *fast = slow->next;

        while (slow && fast)
        {
            if (slow == fast) 
                return fast;
            else {
                slow = slow->next;
                fast = fast->next;
                if (fast)
                    fast = fast->next;
                else return nullptr;
            }
        }
        return nullptr;
    }
};
原文地址:https://www.cnblogs.com/roscangjie/p/11106643.html