Fast and Slow Pointers: Floyd’s Cycle Detection Pattern for Interviews
Learn the fast and slow pointer pattern, why it works, and how to solve linked list cycle and happy number problems with Floyd’s algorithm.
Why this pattern matters in interviews
Fast and slow pointers show up more often than many candidates expect. The pattern is simple, but it solves a class of problems that would otherwise tempt you into extra memory or messy bookkeeping. If you can recognize when two pointers moving at different speeds will eventually meet, you can solve linked list cycle detection, find cycle entry points, and check whether a number is happy — all with constant space.
Interviewers like this pattern because it tests more than implementation skill. It checks whether you can spot structure in a problem, reason about motion over time, and turn that reasoning into a clean algorithm.
Problem statement
The fast and slow pointer pattern usually appears in problems where you need to detect repetition or find a midpoint in a linear structure.
Typical questions include:
- Does a linked list contain a cycle?
- If a cycle exists, where does it begin?
- Is a number a happy number?
- Find the middle node of a linked list.
The core idea is to use one pointer that advances one step at a time (slow) and another that advances two steps at a time (fast). Depending on the problem, their interaction tells you something important:
- If
fastreaches the end, there is no cycle. - If
fastandslowmeet, there is a cycle. - If you reset one pointer and move both one step at a time, they can meet at the cycle entry.
Intuition and insight
The reason this works is easier to see if you think in terms of distance.
In a linked list without a cycle, the fast pointer eventually runs off the end. That gives you a clear stopping condition.
In a linked list with a cycle, both pointers eventually enter the cycle. Once they are inside the loop, the fast pointer gains one node per iteration on the slow pointer. Since the cycle has a finite length, the fast pointer will eventually lap the slow pointer and they will meet.
For a happy number, the same idea applies even though there is no linked list. Each number generates the next number in a deterministic sequence by replacing the number with the sum of the squares of its digits. That sequence either ends at 1 or falls into a cycle. Fast and slow pointers let you detect that cycle without storing every previous number.
This is the main mindset shift:
- You are not “moving two pointers.”
- You are using different speeds to detect structure in a sequence.
When to think of fast and slow pointers
Use this pattern when:
- The input defines a next step from the current state.
- The states form a chain or sequence.
- The sequence might contain a loop.
- You want O(1) extra space.
Good signals include words like:
- cycle
- loop
- repeated state
- linked list
- happy number
- first repeating state
- detect entrance
Step-by-step approach
1) Cycle detection in a linked list
This is the classic Floyd’s cycle detection algorithm.
Idea
Move slow by one node and fast by two nodes.
- If
fastbecomesNone, there is no cycle. - If
slow == fast, a cycle exists.
Python code
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def has_cycle(head: ListNode) -> bool:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return FalseWorked example 1
Suppose the list is:
1 -> 2 -> 3 -> 4 -> 5 -> 3 ...
The node with value 5 points back to node 3.
Pointer movement:
| Step | slow | fast |
|---|---|---|
| 0 | 1 | 1 |
| 1 | 2 | 3 |
| 2 | 3 | 5 |
| 3 | 4 | 4 |
At step 3, the pointers meet, so the list has a cycle.
Why it works
Inside the cycle, fast gains one extra node on slow each iteration. That means the relative distance between them shrinks by 1 modulo the cycle length. Eventually, that distance becomes 0.
2) Find the entry point of a cycle
Once you know a cycle exists, the next common interview question is: where does the cycle begin?
Idea
After the first meeting between slow and fast:
- Leave one pointer where it is.
- Move another pointer to the head.
- Advance both one step at a time.
- The point where they meet again is the cycle entry.
Python code
def detect_cycle_entry(head: ListNode) -> ListNode:
slow = fast = head
# First phase: detect meeting point
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
break
else:
return None
# Second phase: find entry
slow2 = head
while slow != slow2:
slow = slow.next
slow2 = slow2.next
return slowWorked example 2
Consider:
A -> B -> C -> D -> E -> C ...
The cycle starts at C.
After the first phase, suppose slow and fast meet at E.
Now reset slow2 to A and move both one step:
| Step | slow | slow2 |
|---|---|---|
| 0 | E | A |
| 1 | C | B |
| 2 | D | C |
| 3 | E | D |
| 4 | C | E |
At the correct alignment, they meet at C, the cycle entry.
Why it works
Let:
L= distance from head to cycle entryC= cycle lengthx= distance from cycle entry to meeting point
At the first meeting, the fast pointer has traveled twice as far as the slow pointer. The extra distance is a multiple of the cycle length. That relationship means that if you restart one pointer from the head, both pointers will arrive at the cycle entry after the same number of steps.
This is one of those results that feels magical until you write down the distances carefully. Then it becomes a neat piece of arithmetic.
3) Happy number
A happy number is a number that eventually reaches 1 when you repeatedly replace it with the sum of the squares of its digits. If it falls into a cycle that does not include 1, the number is not happy.
This is a perfect use case for fast and slow pointers because the sequence can repeat.
Helper function
def next_number(n: int) -> int:
total = 0
while n > 0:
digit = n % 10
total += digit * digit
n //= 10
return totalApproach
slowmoves one transformation at a time.fastmoves two transformations at a time.- If
fastbecomes1, the number is happy. - If
slow == fastbefore reaching1, a cycle exists and the number is unhappy.
Python code
def is_happy(n: int) -> bool:
slow = fast = n
while True:
slow = next_number(slow)
fast = next_number(next_number(fast))
if fast == 1:
return True
if slow == fast:
return FalseWorked example 3
Check whether 19 is happy.
Sequence:
- 19 -> 1² + 9² = 82
- 82 -> 8² + 2² = 68
- 68 -> 6² + 8² = 100
- 100 -> 1² + 0² + 0² = 1
Since the sequence reaches 1, 19 is happy.
Pointer trace:
| Step | slow | fast |
|---|---|---|
| 0 | 19 | 19 |
| 1 | 82 | 68 |
| 2 | 68 | 1 |
Once fast == 1, we return True.
Now consider 2.
Sequence:
- 2 -> 4 -> 16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4 ...
It falls into a cycle. Fast and slow will eventually meet, so the function returns False.
Alternative approach: use a set
For many cycle problems, you can also store visited states in a set.
Example for linked list cycle detection
def has_cycle_set(head: ListNode) -> bool:
visited = set()
current = head
while current:
if current in visited:
return True
visited.add(current)
current = current.next
return FalseThis is simpler to explain, but it uses extra memory.
Complexity comparison
| Approach | Time | Space | Notes |
|---|---|---|---|
| Fast and slow pointers | O(n) | O(1) | Best when you need constant extra space |
| Hash set / visited set | O(n) | O(n) | Easier to reason about, but uses extra memory |
For interviews, it helps to know both. Start with the set if you need a quick correct solution, then mention Floyd’s algorithm as the space-optimized version.
Common pitfalls
1) Forgetting the loop condition
For linked lists, always check both fast and fast.next before advancing fast by two steps.
while fast and fast.next:Without this guard, you can hit a null reference.
2) Comparing values instead of nodes
In linked list cycle detection, compare node identity, not node values.
if slow == fast:Do not use slow.val == fast.val, because different nodes can store the same value.
3) Assuming fast/slow only works for lists
The pattern works on any deterministic sequence with repeated states, not just linked lists.
4) Missing the entry-point reset logic
Detecting that a cycle exists is a separate step from finding the cycle entrance. Don’t stop after the first meeting if the problem asks for the entry.
Why the mathematics are worth knowing
You do not need to prove Floyd’s algorithm from scratch in every interview, but you should know the core reasoning.
The key property is this:
- If two pointers move at different speeds in a finite cycle, the faster one eventually catches the slower one.
- If the first meeting happens inside the cycle, the distance from the meeting point to the cycle entry has a special relationship with the distance from head to cycle entry.
That’s enough to justify the algorithm confidently and explain it cleanly.
Related problems
Fast and slow pointers are useful for more than the classic cycle questions.
Common related problems include:
- Find the middle of a linked list
- Detect a cycle in a linked list
- Find the start of the cycle
- Happy number
- Palindrome linked list, where you may use slow/fast to split the list before reversing half
- Circular array problems, where a “next index” function creates a state transition graph
Even when a problem doesn’t explicitly mention cycles, ask yourself whether there is an implicit sequence of states. If there is, this pattern may fit.
Key takeaways
- Fast and slow pointers help you detect cycles with O(1) extra space.
- Use
slowfor one step andfastfor two steps. - If
fastreaches the end, there is no cycle. - If
slow == fast, a cycle exists. - To find the cycle entry, reset one pointer to the head and move both one step at a time.
- The pattern applies to linked lists, number transformations, and any deterministic state sequence.
Practice these next
Try these problems to build fluency:
- Linked List Cycle
- Linked List Cycle II
- Happy Number
- Middle of the Linked List
- Palindrome Linked List
If you want to trace the pointer movement step by step, I built an interactive version of this walkthrough at codebrew.ai — it can help if you learn best by watching the variables update live.

