[LeetCode] 142. Linked List Cycle II

Problem

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

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Note: Do not modify the linked list.

Example 1:

1
2
3
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.

142. Linked List Cycle II

Example 2:

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

142. Linked List Cycle II

Example 3:

1
2
3
Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.

142. Linked List Cycle II

Follow-up:

Can you solve it without using extra space?

Explanation

  1. Both slow and fast pointers point to the head.
  2. While fast and fast.next is not null, when slow pointer moves one step, fast pointer moves two steps.
  3. If slow pointer and fast pointer points to the same node, then it means there’s cycle, break out of the while loop.
  4. When out of the while loop, we first check if the fast pointer hits the end, if either fast or fast.next is null, then it means no cycle.
  5. Now, slow pointer moves back to the head. Fast pointer doesn’t move.
  6. Then run both, slow pointer and fast pointer at the same speed, the point the meet is the entry of cycle.

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * 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) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            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;
    }
}