linked-list-cycle-ii (数学证明)

题意:略.

这个题最关键的点在于后面,如何找到循环开始的节点。

      第一阶段,先用快慢指针找到相遇的节点C。(至于为什么,了解一下欧几里德拓展解决二元不定方程。)A是表头。B是开始循环的位置。

      第一次阶段的公式是: 2(x+y)=x+y+n(y+z);    注意一下:n表示快指针比慢指针多跑了n圈!

      那么两边同时减去 x+y    则, x+y= n*(y+z);  注意:这里y+z表示一整圈!则 x等于 (n-1)*y+n*z;  (仔细分析这个式子的含义)

      当n等于1时,是不是x=z,当n=2时,是不是相当于先跑一圈,A-B剩下的等于z,依次类推更大的n

      所以,当一个指针放在C点,第二个指针放在A点, 以相同的而速度向前推进时,相等处就是B点

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if (head == NULL) return NULL;        //空表
        ListNode *slow = head;
        ListNode *fast = head;
        while (fast&&fast->next){
            slow = slow->next;    fast = fast->next->next;
            if (slow == fast)break;            //相遇
        }
        if (fast == NULL || fast->next == NULL)return NULL;
        slow = head;
        while (slow != fast){
            slow = slow->next;
            fast = fast->next;
        }
        return slow;
    }
};
原文地址:https://www.cnblogs.com/ALINGMAOMAO/p/9891454.html