πββοΈ The Tortoise and the Hare: Fast and Slow Pointers
A Racing Story That Solves Problems!
Imagine two friends on a circular running track. One friend is a speedy hare π° who takes two steps at a time. The other is a slow tortoise π’ who takes one step at a time.
Hereβs the magic question: If they start together and keep running, what happens?
- On a straight path: The hare zooms ahead and never looks back.
- On a circular path: The hare eventually catches up to the tortoise from behind! π―
This simple idea is called Fast and Slow Pointers (or Floydβs Cycle Detection). Itβs like having two detectives working at different speeds to find hidden patterns!
π― What Are Fast and Slow Pointers?
Think of it like two runners on a track:
| Pointer | Speed | Think of it as⦠|
|---|---|---|
| Slow | 1 step | π’ Tortoise walking |
| Fast | 2 steps | π° Hare hopping |
The Big Idea:
- Start both at the same spot
- Move them at different speeds
- Watch where they meet (or donβt!)
// The basic pattern
ListNode slow = head;
ListNode fast = head;
while (fast != null &&
fast.next != null) {
slow = slow.next; // π’ 1 step
fast = fast.next.next; // π° 2 steps
}
π Problem 1: Linked List Cycle II
The Story π
Imagine youβre in a maze. You walk and walk, and suddenly you realize: βWait, Iβve been here before!β
Thatβs exactly what happens in a linked list with a cycle β you keep going in circles forever!
The Challenge: Find exactly WHERE the loop starts.
graph TD A[1] --> B[2] B --> C[3] C --> D[4] D --> E[5] E --> C style C fill:#ff6b6b,color:white
Node 3 is where the cycle starts!
How It Works π
Phase 1: Find if thereβs a cycle
- Send tortoise and hare running
- If hare catches tortoise β thereβs a cycle!
Phase 2: Find where cycle starts
- Put one pointer back at the start
- Move BOTH at the same speed (1 step each)
- Where they meet = cycle start! π―
Why Does This Work? π€
Itβs like math magic!
If tortoise traveled distance: D
Then hare traveled: 2D
The extra distance (D) = cycle length Γ K
When we reset one pointer to start and move both at same speed, theyβre guaranteed to meet at the cycle entry!
The Code π»
public ListNode detectCycle(ListNode head) {
// Phase 1: Detect cycle
ListNode slow = head;
ListNode fast = head;
while (fast != null &&
fast.next != null) {
slow = slow.next;
fast = fast.next.next;
// π They met! Cycle exists
if (slow == fast) {
// Phase 2: Find entry
ListNode finder = head;
while (finder != slow) {
finder = finder.next;
slow = slow.next;
}
return finder;
}
}
return null; // No cycle
}
π Problem 2: Happy Number
The Story π
Some numbers are βhappyβ β they have a special secret!
Take any number. Add up the squares of its digits. Do it again. And again.
- Happy numbers eventually reach 1 π
- Sad numbers get stuck in a loop forever π’
Example: Is 19 Happy?
19 β 1Β² + 9Β² = 1 + 81 = 82
82 β 8Β² + 2Β² = 64 + 4 = 68
68 β 6Β² + 8Β² = 36 + 64 = 100
100 β 1Β² + 0Β² + 0Β² = 1 β¨
19 is HAPPY! π
Example: Is 2 Happy?
2 β 4 β 16 β 37 β 58 β 89 β
145 β 42 β 20 β 4 β ... (LOOP!)
2 is SAD π’ (stuck in cycle)
The Connection π‘
Wait! This is just like finding a cycle!
- Happy number β reaches 1 (no cycle)
- Sad number β stuck in a loop (has a cycle!)
Use our tortoise and hare trick!
The Code π»
public boolean isHappy(int n) {
int slow = n;
int fast = n;
do {
slow = sumOfSquares(slow);
fast = sumOfSquares(
sumOfSquares(fast)
);
} while (slow != fast);
return slow == 1;
}
private int sumOfSquares(int n) {
int sum = 0;
while (n > 0) {
int digit = n % 10;
sum += digit * digit;
n /= 10;
}
return sum;
}
π’ Problem 3: Find the Duplicate Number
The Story π
Imagine a classroom with seats numbered 1 to N. Everyone has a ticket with a seat number on it. But wait β one student has a fake ticket with someone elseβs seat number!
You need to find which seat number appears twice!
The Rules:
- Array has
n+1numbers - Numbers are from
1ton - Exactly ONE number repeats
Example
Array: [1, 3, 4, 2, 2]
β β
These two!
Answer: 2 (appears twice)
The Magic Trick π©
Think of the array as a linked list!
- Each number tells you βgo to THIS position nextβ
- Since one number repeats β two arrows point to same place β CYCLE!
Index: 0 1 2 3 4
Value: [1, 3, 4, 2, 2]
Following the arrows:
0 β 1 β 3 β 2 β 4 β 2 β 4 β 2...
β_______|
CYCLE!
The cycle entry point = the duplicate number!
The Code π»
public int findDuplicate(int[] nums) {
// Phase 1: Find meeting point
int slow = nums[0];
int fast = nums[0];
do {
slow = nums[slow];
fast = nums[nums[fast]];
} while (slow != fast);
// Phase 2: Find cycle entry
slow = nums[0];
while (slow != fast) {
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
π§ When to Use Fast & Slow Pointers?
| Situation | Why It Works |
|---|---|
| Cycle detection | Fast catches slow in a loop |
| Finding middle | When fast ends, slow is at middle |
| Finding cycle start | Math magic with distances |
| Detecting patterns | Repeated sequences = cycles! |
π Key Takeaways
-
Fast moves 2x, Slow moves 1x β simple but powerful!
-
If thereβs a cycle β they WILL meet
-
To find cycle start β reset one, move both at 1x
-
Think creatively β arrays can be linked lists!
-
Pattern: Loop or Converge β Try fast/slow!
π Quick Reference
// PATTERN: Cycle Detection
slow = slow.next;
fast = fast.next.next;
// Meet? β Cycle exists!
// PATTERN: Find Cycle Start
// After meeting, reset one to start
// Move both at 1 step β meet at entry!
// PATTERN: Array as Linked List
// Value at index = next index
// Use: slow = nums[slow]
Remember: The tortoise always meets the hare in a circle! π’π°