我们首先想一个问题,在一个环内部,A在B前面,B比A走的快,B的速度是A的2倍,那B是否能够和A走到同一个格子里面?答案是的,只要经过Locate(A)-Locate(B)步之后。相当于每次B都弥补一步。

    那我们再想一个问题,A在B前面,B比A走的快,B的速度是A的k倍,那B是否能够和A走到同一个格子里面?不一定。公式是这样的,A的行走速度是v(格子/秒),B的行走速度是kv(格子/秒),开始A在B前面m的位置处。那么它们相遇的时候,A走的路程是v t = m + kv t,如果t是整数说明有解。

    还要想一个问题,B是在A的第几圈追上A的?是在A的第一圈追上A的,想一下,不管A进入圈圈内时,B在哪里,B的速度是A的两倍,也就是说A走一圈的时候,B就走了两圈,所以他们一定能在A进入第一圈的时候遇上。
    AB之间最坏的情况就是B刚好超过一点点在A前面。因为AB之间的距离差是小于一圈的,所以说,当A用v走一圈时候,B用一个v在紧跟A,然后在一圈之内,B可以用另一个v来弥补距离差追上A。假设一圈是S,那么A走一圈的时间是S/v,而AB之间的距离是S1 < S,如果用v来弥补,需要的时间是S1/v,小于S/v,也就是可以在A走完一圈之间把这个距离弥补上来。

    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * ListNode *next;
    6. * ListNode(int x) : val(x), next(NULL) {}
    7. * };
    8. */
    9. class Solution {
    10. public:
    11. ListNode *detectCycle(ListNode *head) {
    12. if(!head || !head->next) return nullptr;
    13. ListNode *fast = head->next, *slow = head;
    14. while(fast != slow)
    15. {
    16. if(!fast || !fast->next) return nullptr;
    17. fast = fast->next->next;
    18. slow = slow->next;
    19. }
    20. slow = head;
    21. fast = fast->next;
    22. while(fast != slow)
    23. {
    24. fast = fast->next;
    25. slow = slow->next;
    26. }
    27. return fast;
    28. }
    29. };