Linked List Cycle II Solution
Detect whether a cycle exists and return the node where the cycle begins. If no cycle exists, return null.
Problem Statement
This is the follow-up to LC 141. Detecting a cycle is not enough anymore β we must recover the exact node where the loop begins, using only O(1) extra space.
HashSet of Visited Nodes β O(n) Space
Walk the list, storing each node reference in a HashSet. The first node you encounter twice is exactly the cycle entry.
Floyd's Algorithm + Reset Pointer β O(1) Space
First run the standard slow/fast cycle detection. If they never meet, there is no cycle. If they do meet inside the loop, reset one pointer to head while keeping the other at the meeting point. Move both one step at a time. Their next meeting point is the cycle entry.
- Phase 1: detect whether a meeting happens.
- If no meeting, return
null. - Phase 2: set one pointer to
head. - Move both pointers one step at a time.
- The node where they meet is the cycle entry.
- If the non-cycle prefix has length
aand the cycle length isc, then when slow and fast first meet, the meeting point is exactlyasteps away from the cycle entry when measured around the loop. - So one pointer from
headand one from the meeting point reach the entry together.
Visual Walkthrough
Trace 3 β 2 β 0 β -4 β (back to 2).
Code β Java & Python
Complexity Analysis
| Approach | Time | Space | Trade-off |
|---|---|---|---|
| HashSet | O(n) | O(n) | Simple and direct, but not constant space. |
| Floyd's cycle entry β optimal | O(n) | O(1) | Detects and locates the entry with two pointers only. |
Edge Cases & Pitfalls
| Case | Expected behavior | Why it matters |
|---|---|---|
| No cycle | Return null | Fast pointer reaches the end. |
| Cycle starts at head | Return head | The reset logic must still work. |
| Single-node self-cycle | Return that node | Fast and slow meet immediately after one loop. |
| Meeting point β entry | Still recover the entry | The first collision is usually inside the loop, not at the start. |
| Comparing node values | Wrong | Use node identity/reference equality, not val. |
head; the other must stay at the meeting point. Then move both one step at a time until they meet at the entry.