150NeetCode 150

41.Linked List Cycle

EasyBlind 75Linked List ยท 7/11

Problem

Given head, the head of a linked list, determine whether the list contains a cycle โ€” that is, whether some node can be reached again by repeatedly following next pointers.

Internally, a cycle is created by connecting the tail to the node at index pos (pos = -1 means no cycle), but pos is not passed to your function. Return true if there is a cycle, otherwise false.

Examples

Input:  head = [3, 2, 0, -4], pos = 1
Output: true
Explanation: The tail (-4) connects back to the node at index 1 (value 2).
Input:  head = [1, 2], pos = 0
Output: true
Explanation: The tail connects back to the head.
Input:  head = [1], pos = -1
Output: false
Explanation: Following next eventually reaches null.

Constraints

  • The number of nodes in the list is in the range [0, 10^4].
  • -10^5 <= Node.val <= 10^5
  • pos is -1 or a valid index in the linked list.

๐Ÿ’ก Key Insight

A list without a cycle always ends at null; a list with a cycle never does. To tell the two apart without extra memory, use two runners at different speeds (Floyd's tortoise and hare): if there is a loop, the fast runner laps the slow one and they must land on the same node; if not, the fast runner simply reaches null.

Brute Force (Look Back for Each Node)

TimeO(nยฒ)SpaceO(1)

Intuition

In a cyclic list, there is exactly one node whose next points back to a node at the same or an earlier position. Walk the list keeping a position counter; for each node, scan the prefix of the list to see whether its next is one of the nodes already visited.

Algorithm

  1. curr = head, pos = 0.
  2. While curr != null:
    • Walk probe from head through positions 0..pos; if probe == curr.next, return true.
    • curr = curr.next, pos++.
  3. Return false.

Visualization

3 -> 2 -> 0 -> -4 -> (back to 2)
pos 0 (3):  next=2, prefix [3]          no
pos 1 (2):  next=0, prefix [3,2]        no
pos 2 (0):  next=-4, prefix [3,2,0]     no
pos 3 (-4): next=2, prefix [3,2,0,-4]   2 found -> true

Code

java
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode curr = head;
        int pos = 0;
        while (curr != null) {
            // Does curr.next point back to any node at position 0..pos?
            ListNode probe = head;
            for (int i = 0; i <= pos; i++) {
                if (probe == curr.next) {
                    return true;
                }
                probe = probe.next;
            }
            curr = curr.next;
            pos++;
        }
        return false;
    }
}

Complexity

  • Time: O(nยฒ) โ€” each node rescans the prefix before it.
  • Space: O(1) โ€” just pointers and a counter.

Complexity Comparison

Approach Time Space
Look Back for Each Node O(nยฒ) O(1)
Hash Set O(n) O(n)
Floyd's Tortoise and Hare O(n) O(1)

Common Pitfalls

  • Checking slow == fast before moving them โ€” they both start at head, so you would always return true.
  • Looping on fast.next != null without first checking fast != null, causing a NullPointerException.
  • Storing node values in the set instead of node references โ€” duplicate values do not imply a cycle.
  • Forgetting the empty list: head == null must return false.