The Tortoise and The Hare
[!NOTE] This module explores the core principles of Fast & Slow Pointers, deriving solutions from first principles and hardware constraints to build world-class, production-ready expertise.
1. Concept Definition
How do you detect if a Linked List has a cycle (a loop)?
- Naive Approach: Use a
HashSetto store visited nodes. If you see a duplicate, there’s a cycle.- Time: O(N)
- Space: O(N) (Expensive!)
- Optimal Approach: Floyd’s Cycle-Finding Algorithm.
- Time: O(N)
- Space: O(1)
The core idea is using two pointers moving at different speeds. If there is a cycle, the fast pointer will eventually “lap” the slow pointer.
2. Interactive Analysis
Watch the race. Can the Hare catch the Tortoise?
Ready to race.
Slow: Node 0
Fast: Node 0
3. Intuition
The Convergence Proof
- Let m be the distance from the
headto the start of the cycle. - Let k be the length of the cycle.
- Let i be the number of steps taken.
- Position of Tortoise: S(i) = (i - m) mod k (once inside the cycle).
- Position of Hare: F(i) = (2i - m) mod k.
- The pointers meet when F(i) equiv S(i) pmod k.
- This implies (2i - m) - (i - m) = n cdot k (for some integer n).
- Simplifying gives i = n cdot k. Since i can be any multiple of the cycle length k, and the Tortoise hasn’t even finished one lap when the Hare (moving twice as fast) laps it, they are guaranteed to meet.
4. Implementation
We initialize both pointers at head.
- If
fastreachesnull, the list ends (no cycle). - If
fast == slow, there is a cycle.
Java
Go
public boolean hasCycle(ListNode head) {
if (head == null) return false;
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next; // 1 step
fast = fast.next.next; // 2 steps
if (slow == fast) {
return true; // Cycle detected
}
}
return false; // Reached null
}
func HasCycle(head *ListNode) bool {
if head == nil {
return false
}
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
return true
}
}
return false
}
5. Complexity Analysis
| Strategy | Time | Space | Notes |
|---|---|---|---|
| Floyd’s Algorithm | O(N) | O(1) | Guaranteed to meet within one cycle length. |
| Hash Set | O(N) | O(N) | Naive approach. |