Grokking the Coding Interview logo
HomeCoursesBlog
← Back to Blog
Article

Fast & Slow Pointers: The Cycle-Detection Pattern Explained

Fast & Slow Pointers: The Cycle-Detection Pattern Explained

TL;DR: Fast & slow pointers is two pointers with a twist: instead of starting at different positions, the pointers move at different speeds, usually 1 step and 2 steps. That one change buys you three superpowers in O(1) space: detecting whether a sequence loops (the pointers must eventually meet inside a cycle), finding the middle of a linked list in one pass (when fast finishes, slow is halfway), and locating exactly where a cycle begins (Floyd's second phase). Learn the three templates and the one-sentence argument for why the meeting is guaranteed, and a whole family of linked list questions becomes mechanical.

This is the third deep dive in our pattern series, after sliding window and two pointers. Fast & slow pointers (you'll also hear "tortoise and hare" or "Floyd's cycle detection") is the smallest pattern of the three, but it punches far above its weight in interviews: it's the standard way interviewers test whether you can reason about pointer mechanics rather than reciting solutions, and the follow-up questions ("okay, now find where the cycle starts") are pre-scripted at most companies.

The tell: how to recognize fast & slow pointers in an interview

You should suspect this pattern when a problem involves a linked structure or an iterated sequence, plus any of these:

  • "does this linked list contain a cycle?"
  • "find the middle of the linked list" (especially "in one pass")
  • "is this linked list a palindrome?" / "reorder the list"
  • a process you apply repeatedly and that might loop forever (Happy Number's digit-square sums)
  • "find the duplicate number without modifying the array and in O(1) space"

The strongest signal is a linked list plus an O(1) space requirement. Any cycle question can be solved with a hash set of visited nodes, and interviewers know it; the entire point of asking is to see whether you know the pointer-based version that uses no extra memory. If the interviewer says "can you do it without extra space?", they are asking for this pattern by name.

Why the pointers must meet (say this out loud)

The whole pattern rests on one argument, and interviewers grade the argument more than the code. Move slow one step and fast two steps per tick. If there's no cycle, fast hits the end and you're done. If there is a cycle, both pointers eventually end up inside it, and inside a cycle the gap between them shrinks by exactly one node per tick (fast gains one step per tick, relative to slow). A gap that shrinks by one at a time can't skip over zero, so the pointers must land on the same node within one lap. That's the whole proof: relative speed is 1, so the gap walks down to zero.

Template 1: does a cycle exist?

def has_cycle(head):                    # LeetCode 141
    slow = fast = head
    while fast and fast.next:
        slow = slow.next                # 1 step
        fast = fast.next.next           # 2 steps
        if slow is fast:
            return True
    return False

Note the loop condition guards fast and fast.next, never slow: fast is always ahead, so only fast can fall off the end. This is O(n) time, O(1) space, and about eight lines, which is exactly why the explanation is what separates candidates.

Template 2: find the middle

Same mechanics, different exit: when fast reaches the end of a list with no cycle, slow has covered half the distance and is standing on the middle.

def middle_node(head):                  # LeetCode 876
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
    return slow                         # middle (second middle if even length)

This looks like a party trick until you see what it unlocks. Palindrome Linked List: find the middle, reverse the second half in place (using the reversal technique from the two pointers reader-writer family), then compare the two halves. Reorder List: find the middle, reverse the second half, interleave. Both are common interview questions, and both are just "middle + reverse + walk", three tools you now own.

Template 3: where does the cycle start?

The pre-scripted follow-up. After slow and fast meet inside the cycle, reset one pointer to the head, then move both at one step per tick. Where they meet again is the first node of the cycle.

def detect_cycle_start(head):           # LeetCode 142
    slow = fast = head
    while fast and fast.next:
        slow, fast = slow.next, fast.next.next
        if slow is fast:                # phase 1: they met in the cycle
            slow = head                 # phase 2: reset one to head
            while slow is not fast:
                slow, fast = slow.next, fast.next
            return slow                 # cycle entrance
    return None

The intuition for why phase 2 works, in one sentence you can say in an interview: when they first meet, the distance from the head to the cycle entrance equals the distance from the meeting point forward to that same entrance (this falls out of the fact that fast walked exactly twice as far as slow), so two pointers advancing in lockstep from those two starting points arrive together at the entrance.

The pattern beyond linked lists

The elegant part, and the part that earns senior-level points, is realizing that anything you iterate repeatedly is a linked list in disguise: state points to next state.

  • Happy Number (LeetCode 202): repeatedly replace a number with the sum of squares of its digits. Either you reach 1, or you loop forever. "Loop forever" is a cycle, so run fast & slow on the number sequence itself. No nodes, no pointers, same template.
  • Find the Duplicate Number (LeetCode 287): an array of n+1 numbers in range 1..n. Read each value as "the index of the next node" and the array is a linked list where the duplicate value creates a cycle entrance. Template 3 finds it with no modification and O(1) space. This is a famous interview problem precisely because the mapping is the hard part; the code afterward is 12 lines you already have.

When you can explain that mapping, you're demonstrating exactly the recognition skill that pattern-based prep is about: not "I memorized 287", but "this is a cycle problem wearing an array costume."

Want each variation taught, not just listed? The fast & slow pointers chapter of Grokking the Coding Interview builds the pattern from cycle detection through the array-as-linked-list problems with visual explanations and code in six languages, then does the same for all 42 patterns (32 common + 10 advanced).

The three mistakes that sink candidates

1. Null-crashing the fast pointer. Every advance of fast needs both fast and fast.next checked first, because fast.next.next on a null dereferences. Writing while fast.next and fast.next.next versus while fast and fast.next also changes which middle you get on even-length lists; know which one your solution needs before you code, and say it.

2. Botching the meet check. Compare node identity (slow is fast), not node values, since values repeat. And check after moving both pointers, not before: they start at the same node, so a pre-move check "detects" a cycle instantly on every input.

3. Forgetting that phase 2 runs at equal speed. The most common Cycle II failure: after resetting one pointer to head, candidates keep moving fast at 2x. Both pointers move one step per tick in phase 2. If your cycle-start answer is wrong on a test case, check this line first.

And a soft mistake: reaching for a hash set when the interviewer emphasizes space. A visited-set solution is correct, and it's fine to mention it as the 30-second baseline, but treat it as the warm-up, not the answer. The O(1)-space version is what the question exists to test.

Practice ladder

In order; each rung adds one wrinkle.

  1. Linked List Cycle (E): template 1 verbatim; rehearse the shrinking-gap argument out loud.
  2. Middle of the Linked List (E): template 2 verbatim.
  3. Happy Number (E): template 1 with no linked list; the first costume change.
  4. Linked List Cycle II (M): template 3; rehearse the phase-2 explanation.
  5. Palindrome Linked List (M): middle + reverse second half + compare.
  6. Reorder List (M): middle + reverse + interleave; a Meta favorite.
  7. Find the Duplicate Number (M): the array-as-linked-list mapping; the pattern's most-asked hard application.
  8. Stretch goal: Circular Array Loop (M): cycles with direction constraints, where the bookkeeping, not the pattern, is the challenge.

Then write the tell in your own words ("I should suspect fast & slow pointers when ___") and move on. Six problems with the arguments understood beats twenty solved by pattern-matching to memorized code, the difference we keep coming back to in Why Is LeetCode So Hard?

The takeaway

Fast & slow pointers is one mechanical idea, two pointers at different speeds, backed by one argument, the gap shrinks by one per tick so a meeting is guaranteed. That buys cycle detection, middle-finding, and cycle-entrance location, all in O(1) space, and it generalizes to any repeatedly-applied process, not just linked lists. Master the three templates, and more importantly the two sentences that justify them, because the justifications are what your interviewer is actually grading. Next in the series: Merge Intervals, where the pattern is less about pointers and more about learning to think in overlaps.

Go deeper: Grokking the Coding Interview teaches all 42 patterns (32 common + 10 advanced) across 300+ problems in six languages, for a one-time $79. Short on time? Grokking 75 distills the essentials into a 6-week plan.

FAQs

What is the fast and slow pointers technique in simple terms? Run two pointers through the same sequence, one moving one step at a time and one moving two. If the sequence loops, the fast pointer laps the slow one and they collide, proving a cycle exists. If it doesn't loop, the fast pointer reaches the end in half the iterations, which also makes the slow pointer land on the middle.

Why can't the fast pointer jump over the slow one? Because their relative speed is exactly one node per tick. Inside a cycle, the gap between them shrinks by one each step, and a gap shrinking by one at a time must pass through zero, which is the meeting. (At speed 3 or higher this guarantee breaks, which is why the canonical version uses 2.)

How is fast & slow pointers different from regular two pointers? Regular two pointers vary the starting positions (both ends, or reader/writer) with equal speeds. Fast & slow varies the speeds with equal starting positions. Use position-based two pointers for pair-finding and in-place edits; use speed-based pointers for cycles and midpoints.

Is Floyd's cycle detection actually asked in FAANG interviews? Constantly, usually disguised. Linked List Cycle II and Find the Duplicate Number are the two most common forms, and Reorder List (which uses the middle-finding template) is a Meta staple. The bar isn't writing the code, it's explaining why the meeting is guaranteed and why phase 2 finds the entrance.

Can I just use a hash set instead? For correctness, yes: store visited nodes, return true on a repeat. It costs O(n) space, and the interviewer will immediately ask for O(1). Mention the set as your baseline, then give the pointer version. Knowing both, and when each is appropriate, reads as maturity rather than memorization.

One-Stop Portal For Coding Interviews.
Follow us:
Copyright © 2025 Coding Interview All rights reserved.