Detect a meeting
Choose Structure in the visualizer and compare List with a cycle, List with no cycle, and Cycle back to the start. Use Auto-Run to watch the fast pointer catch the slow pointer. Compare node identity, not just stored values: different nodes can contain equal values.
Why they meet
Once both pointers are inside the loop, fast gains one node on slow at every step. Their distance around the cycle shrinks by one, so they must eventually land on the same node. If there is no loop, fast instead reaches the end.
Find the cycle entry
After a meeting, reset one pointer to the head. Move both one step at a time. They meet at the first node of the cycle. If the non-cyclic prefix has length μ and the cycle length is λ, the first meeting’s position in the cycle makes both pointers reach the entry after μ more steps.
Floyd’s algorithm takes O(n) time and O(1) extra space. A visited-node set also detects a loop in linear time, but stores up to n node references. Choose it when simpler debugging is more useful than saving memory.
In the classic duplicate-number problem, each array value can be treated as the next index to visit. That creates a linked structure over indices, and Floyd’s method can locate the cycle without modifying the array. The input constraints are essential for this mapping to be valid.
Graph cycle detection is a different problem: use DFS with graph-specific state, or topological sorting for directed acyclic graphs. See depth-first search and topological sort.
Common mistakes with Cycle Detection
- Advancing fast by one: the pointers no longer close the gap at the required rate.
- Checking values rather than nodes: equal values do not mean two pointers reference the same node.
- Forgetting the empty-list case: check for
None before accessing .next. - Assuming every cycle detector is interchangeable: linked-list pointers and graph edges need different state and reasoning.