142. Linked List Cycle II

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

If there is cycle in a given linked list, pointers with step size of 1 and 2 will eventually meet. When they meet, 2 * distance(slow) = distance(fast).

Let’s assume that the pointers walk around the cycle (if it exists) clockwise.

  • F : the distance from head to the cycle entrance
  • a: the distance from cycle entrance to intersection
  • b: the distance from intersection to cycle entrance

Thus 2 * (F + a) = F + N(a + b) + a, then F = b + (N - 1)(a + b). After we find the intersection, let one pointer go from the intersection and the other from head, both of them have a same step size. We will get the cycle entrance when they meet.

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        // corner case
        if (head == null) {
            return null;
        }
        
        // phase 1: find the intersection
        ListNode slow = head;
        ListNode fast = head;
        ListNode intersection = null;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                intersection = fast;
                break;
            }
        }
        if (intersection == null) {
            return null;
        }
        
        // phase 2: find the cycle entrance
        ListNode ptr1 = head;
        ListNode ptr2 = intersection;
        while (ptr1 != ptr2) {
            ptr1 = ptr1.next;
            ptr2 = ptr2.next;
        }
        return ptr1;
    }
}