Sweaty Imposter

Linked List Cycle

EasyFast & Slow Pointers (Floyd's)Blind 75JuniorOpen on LeetCodeUpdated

You're given the head of a singly linked list. Return true if following next links from the head ever brings you back to a node you've already visited (the list has a cycle), and false if you eventually reach null. The examples write the list as its values plus pos, the index of the node the tail links back to; pos = -1 means the tail points to null. Your function receives only head, not pos. Can you use O(1) extra memory?

Examples

head = [3,2,0,-4], pos = 1 returns true

320-4
The tail links back to index 1, closing a loop of three nodes.

The tail, -4, links back to the node at index 1 (value 2). Walking from the head visits 3, 2, 0, -4, 2, 0, -4, and so on, never reaching null.

head = [1], pos = -1 returns false

1null
One node whose next is null.

The single node's next is null, so the walk ends after one node and nothing is visited twice.

Constraints

  • 0 <= n <= 10^4

Hints

Hint 1

If two runners moved at different speeds around a track, what would tell you the track is a loop?

Hint 2
A pointer toward the approach
Hint 3
The full approach, step by step

Drill This: Your Approach First

Approach

Floyd's tortoise and hare: move slow one node per step and fast two. Without a cycle, fast reaches null and you return false. With a cycle, both pointers end up circling it, and the gap between them shrinks by one node each step, so fast catches slow within one lap. Compare node identity, not values.

Time

O(n)

Space

O(1)

Pitfall

Check both fast and fast.next before jumping two nodes; checking only one crashes at the end of either an odd-length or an even-length list. Compare nodes by identity, not value, since distinct nodes can hold the same value.

Solutions

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow = head, fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) return true;
        }
        return false;
    }
}
Drill This