Web Analytics

๐Ÿข๐Ÿ‡ Cycle Detection - Floyd's Algorithm

Intermediate ~25 min read โญ Top Interview Question

Imagine a linked list where the last node points back to an earlier node instead of null - creating an infinite loop! Floyd's Tortoise and Hare algorithm detects this in O(n) time with O(1) space. This elegant solution appears frequently at Google, Amazon, Microsoft, and Facebook!

๐ŸŽฏ Interview Alert!

Floyd's algorithm is a MUST-KNOW:

  • โœ… Google - Common question
  • โœ… Amazon - Frequently asked
  • โœ… Microsoft - Standard interview
  • โœ… Facebook - Regular appearance
  • โœ… LinkedIn - Popular question

The O(1) space solution is what separates good from great!

The Problem

Detect if a linked list has a cycle

Example WITH cycle:

1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 5
        โ†‘           โ†“
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        
Cycle exists! Node 5 points back to node 3

Example WITHOUT cycle:

1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 5 โ†’ null

No cycle - ends with null

Challenge: Detect cycle in O(1) space (no HashSet!)

Floyd's Tortoise and Hare ๐Ÿข๐Ÿ‡

The brilliant insight: Use two pointers moving at different speeds!

The Algorithm

def has_cycle(head):
    slow = head  # ๐Ÿข Tortoise - moves 1 step
    fast = head  # ๐Ÿ‡ Hare - moves 2 steps
    
    while fast and fast.next:
        slow = slow.next      # Move 1 step
        fast = fast.next.next # Move 2 steps
        
        if slow == fast:
            return True  # They met - cycle!
    
    return False  # Hare reached end - no cycle

That's it! Just 9 lines to detect cycles.

See It in Action

Watch the tortoise and hare move through the list:

Why It Works

๐Ÿ’ก The Race Track Analogy

Think of a circular race track:

  • ๐Ÿข Tortoise runs at 1 mph
  • ๐Ÿ‡ Hare runs at 2 mph (twice as fast!)
  • If the track is circular, the hare will eventually lap the tortoise
  • They MUST meet at some point!

Same with linked lists: If there's a cycle, fast will catch slow!

Step-by-Step Example

Let's trace through a list with a cycle:

List structure:

1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 5
        โ†‘           โ†“
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Step 0: Both start at node 1

๐Ÿข๐Ÿ‡ at 1

Step 1: Slow moves to 2, Fast moves to 3

๐Ÿข at 2, ๐Ÿ‡ at 3

Step 2: Slow moves to 3, Fast moves to 5

๐Ÿข at 3, ๐Ÿ‡ at 5

Step 3: Slow moves to 4, Fast moves to 4 (via cycle!)

๐Ÿข at 4, ๐Ÿ‡ at 4 โ†’ They met! Cycle detected!

Finding the Cycle Start

Once we know there's a cycle, where does it start?

The Magic Trick

def find_cycle_start(head):
    # Step 1: Detect cycle and find meeting point
    slow = fast = head
    
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            break  # Found meeting point
    else:
        return None  # No cycle
    
    # Step 2: Find cycle start
    slow = head  # Move slow to head
    
    while slow != fast:
        slow = slow.next  # Both move 1 step
        fast = fast.next
    
    return slow  # This is the cycle start!

Why Does This Work?

๐Ÿ’ก The Mathematics

Let's define:

  • x = distance from head to cycle start
  • y = distance from cycle start to meeting point
  • C = cycle length

When they meet:

  • Slow traveled: x + y
  • Fast traveled: x + y + nC (n complete cycles)
  • Fast = 2 ร— Slow (twice the distance)

Therefore:

x + y + nC = 2(x + y)
x + y + nC = 2x + 2y
nC = x + y
x = nC - y

This means: Distance from head to cycle start (x) equals distance from meeting point to cycle start (nC - y)!

So: If we move both pointers at same speed, they meet at cycle start!

The Complete Code

Output
Click Run to execute your code

Complexity Analysis

Operation Time Space Notes
Detect cycle O(n) โœ“ O(1) โœ“โœ“ Floyd's algorithm
Find cycle start O(n) โœ“ O(1) โœ“โœ“ Two-phase approach
Get cycle length O(n) โœ“ O(1) โœ“โœ“ Count after detection
Remove cycle O(n) โœ“ O(1) โœ“โœ“ Find start, break link
Using HashSet O(n) O(n) Not optimal!

Common Mistakes

โŒ Mistake #1: Not Checking fast.next

# WRONG - crashes if fast.next is null!
while fast:
    fast = fast.next.next  # Crashes!

# RIGHT - check both fast and fast.next
while fast and fast.next:
    fast = fast.next.next  # Safe!

โŒ Mistake #2: Moving Both Same Speed

# WRONG - both move 1 step
slow = slow.next
fast = fast.next  # They'll never meet!

# RIGHT - fast moves 2 steps
slow = slow.next
fast = fast.next.next  # Twice as fast!

โŒ Mistake #3: Using Extra Space

# WRONG - uses O(n) space
visited = set()
while current:
    if current in visited:
        return True
    visited.add(current)

# RIGHT - O(1) space with Floyd's
# (Use the algorithm above!)

Interview Variations

Common Follow-ups

  1. Detect if cycle exists โœ“ (covered)
  2. Find where cycle starts โœ“ (covered)
  3. Find length of cycle โœ“ (covered)
  4. Remove the cycle โœ“ (covered)
  5. Find intersection of two lists (similar technique!)
  6. Check if list is palindrome (uses slow/fast pointers)

Interview Tips

๐Ÿ’ก How to Ace This Question

  • โœ… Explain the analogy: "Like a race track - faster runner laps slower"
  • โœ… Draw it out: Visualize the cycle and pointer movements
  • โœ… Mention O(1) space: This is the key advantage over HashSet!
  • โœ… Handle edge cases: Empty list, single node, no cycle
  • โœ… Explain the math: Show you understand WHY it works
  • โœ… Know the variations: Finding start, length, removal

โœ… What Interviewers Want to See

  • Understanding of two-pointer technique
  • Ability to optimize space complexity
  • Knowledge of mathematical reasoning
  • Handling edge cases properly
  • Clear communication of algorithm

Real-World Applications

Where Is This Used?

  • Deadlock detection: Finding circular dependencies
  • Memory leak detection: Circular references
  • Graph algorithms: Detecting cycles in graphs
  • Duplicate detection: Finding repeated sequences
  • Infinite loop detection: Program analysis

Summary

Floyd's Tortoise and Hare

  1. Use two pointers: slow (1 step) and fast (2 steps)
  2. If cycle exists: They will meet inside the cycle
  3. If no cycle: Fast reaches null
  4. To find start: Move one to head, both move 1 step, meet at start
  5. O(n) time, O(1) space: Optimal solution!

Interview tip: This is a classic two-pointer problem. The key insight is using different speeds to detect cycles. Always explain the race track analogy - it shows deep understanding!

What's Next?

You've mastered cycle detection! Next: Two Pointer Techniques - finding middle, nth from end, and palindrome checking!

Practice: Try implementing all 4 operations (detect, find start, get length, remove). Draw cycles on paper to visualize!