142 - Linked List Cycle II

#medium

Given the head of a linked list, return the node where the cycle begins. If there is no cycle, return null.

There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to (0-indexed). It is -1 if there is no cycle. Note that pos is not passed as a parameter.

Do not modify the linked list.

Example 1:

Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

思路

  • 一樣使用快指針與慢指針,快指針比慢指針快一步。
  • 慢指針與快指針在第一圈中相遇,在快指針第x圈後遇到第一圈正在走的慢指針。

slow = x + y
fast = x + y + n( y + z )

2x slow = fast
x = (n - 1) (y + z ) + z
n =1時,x=z 在入口處相遇,必定在第一圈相遇。

Solution

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast != NULL && fast->next != NULL) {
            slow = slow->next;
            fast = fast->next->next;
            // 快慢指針相遇,此時從head 和 相遇點,同時查找直至相遇
            if (slow == fast) {
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while (index1 != index2) {
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index2; // 返迴環的入口
            }
        }
        return NULL;
    }
};