PROBLEM-SOLVING PATTERNS / ALGORITHM BRIEF

Fast and slow pointers

The fast and slow pointers technique (Floyd's tortoise and hare) moves two pointers through a sequence at different speeds, usually one step and two steps.

IntermediatePhase 03 / Topic 2 of 10Mental modelComplexityEdge cases
01

Overview

The fast and slow pointers technique (Floyd's tortoise and hare) moves two pointers through a sequence at different speeds, usually one step and two steps. If there is a cycle, the fast pointer eventually laps the slow one and they meet. If there is no cycle, the fast pointer reaches the end first.

The same idea finds the middle of a list in one pass (when fast reaches the end, slow is halfway), the start of a cycle, and duplicate numbers in arrays whose values act as next pointers. It uses O(1) extra memory, which is why interviewers love it as a follow-up to hash-set solutions.

Runners on a circular track

Two runners start together, one twice as fast as the other. On a straight road, the fast runner simply finishes first. On a circular track, the fast runner gains one lap-position per step and must eventually catch the slow runner from behind.

02

When to use it

  • Detect a cycle in a linked list or in any sequence x -> f(x).
  • Find the middle node, or split a list into halves.
  • Find where a cycle begins.
  • O(1) space is required where a visited set would otherwise be used.
  • Find the kth node from the end (a fixed gap variant).
03

Problem patterns it solves

Cycle detection

Recognize it when: does the list or sequence loop back on itself.

  • 141. Linked List Cycle
  • 202. Happy Number
  • 457. Circular Array Loop
Cycle entry point

Recognize it when: where does the cycle begin; find the duplicate with O(1) space.

  • 142. Linked List Cycle II
  • 287. Find the Duplicate Number
Middle of the list

Recognize it when: split in half, palindrome check, reorder, sort a list.

  • 876. Middle of the Linked List
  • 234. Palindrome Linked List
  • 143. Reorder List
  • 148. Sort List
  • 2095. Delete the Middle Node
Fixed gap between pointers

Recognize it when: kth from the end, remove nth from the end.

  • 19. Remove Nth Node From End of List
  • 61. Rotate List
  • 1721. Swapping Nodes in a Linked List
04

Where it is used in real software

Detecting infinite loops in state machines

Iterating a function over states (pseudo-random generators, workflow transitions) can loop; Floyd's algorithm detects it without storing visited states.

Pollard's rho factorization

This integer factorization algorithm uses Floyd's cycle detection on a pseudo-random sequence modulo n.

Corrupted linked structures

Memory debuggers and garbage collectors guard against cyclic corruption in linked lists.

Streaming midpoints

Splitting a singly linked sequence without knowing its length is a standard step in merge-sorting linked data.

05

Key terms

Tortoise (slow)
Moves one step per iteration.
Hare (fast)
Moves two steps per iteration.
Meeting point
Where slow and fast coincide inside a cycle.
Cycle entry
First node of the cycle; found by resetting one pointer to the head.
Functional graph
Each value points to exactly one next value, e.g. i -> nums[i].
06

Floyd's algorithm for the cycle start

  1. 1
    Phase 1: detect

    slow = slow.next, fast = fast.next.next until they meet (cycle) or fast reaches null (no cycle).

  2. 2
    Phase 2: reset

    Move one pointer back to the head. Keep the other at the meeting point.

  3. 3
    Move both one step at a time

    They meet exactly at the cycle entry.

  4. 4
    Why it works

    If the distance from head to the entry is a and the meeting point is b steps into a cycle of length c, then 2(a + b) = a + b + kc, so a = kc - b. Walking a steps from the meeting point lands on the entry.

Finding the middle of 1 -> 2 -> 3 -> 4 -> 5
Step 1 / 4
S F
1
0
2
1
3
2
4
3
5
4

STEP 1Both pointers start at the head.

07

Find the duplicate number with O(1) space

nums = [1, 3, 4, 2, 2]; treat index -> nums[index] as a next pointer

Step 1 / 6
PhaseslowfastNote
Startnums[0] = 1nums[0] = 1both start at value 1
Detect 1nums[1] = 3nums[nums[1]] = nums[3] = 2slow 1 step, fast 2 steps
Detect 2nums[3] = 2nums[nums[2]] = nums[4] = 2meet at 2 (inside the cycle)
Resetnums[0] = 12slow back to the start
Find 1nums[1] = 3nums[2] = 4both move 1 step
Find 2nums[3] = 2nums[4] = 2meet at 2: the duplicate

NOWPhase: Start | slow: nums[0] = 1 | fast: nums[0] = 1 | Note: both start at value 1

The duplicate value is where two indexes point, which is the entry of the cycle. O(n) time and O(1) space, without modifying the array.

08

Implementation

function hasCycle(head) {  let slow = head, fast = head;  while (fast && fast.next) {    slow = slow.next;    fast = fast.next.next;    if (slow === fast) return true;  }  return false;} function detectCycle(head) {  let slow = head, fast = head;  while (fast && fast.next) {    slow = slow.next;    fast = fast.next.next;    if (slow === fast) {      slow = head; // phase 2      while (slow !== fast) {        slow = slow.next;        fast = fast.next;      }      return slow;    }  }  return null;} function middleNode(head) {  let slow = head, fast = head;  while (fast && fast.next) {    slow = slow.next;    fast = fast.next.next;  }  return slow; // second middle for even lengths} function findDuplicate(nums) {  let slow = nums[0], fast = nums[0];  do {    slow = nums[slow];    fast = nums[nums[fast]];  } while (slow !== fast);  slow = nums[0];  while (slow !== fast) {    slow = nums[slow];    fast = nums[fast];  }  return slow;}
09

Complexity and performance

TimeO(n)

Fast catches slow within one lap of the cycle.

SpaceO(1)

Two pointers only.

Hash set alternativeO(n) space

Simpler but uses memory.

10

Trade-offs

vs hash set

A visited set is easier to write and also gives the entry node directly, but costs O(n) memory.

Modifying the list

Palindrome checks reverse the second half; restore it afterward if the caller needs the original list.

11

Variants and related techniques

First vs second middle

Starting fast at head.next returns the first middle for even-length lists, which is what merge sort splitting needs.

Brent's algorithm

A faster cycle detection using powers of two; same O(1) space.

Cycle length

After meeting, keep one pointer fixed and count steps until the other returns.

12

Common mistakes

  • Checking only fast.next.

    Fix: The loop condition must be fast && fast.next, in that order.

  • Comparing values instead of node references.

    Fix: Use slow === fast; different nodes can hold equal values.

  • Wrong start in findDuplicate.

    Fix: Start both at nums[0] and use a do-while so they move before comparing.

13

Interview questions

Why must the fast pointer meet the slow pointer in a cycle?

Once both are inside the cycle, the gap between them shrinks by one each step (fast gains one position per step), so it reaches zero within one cycle length.

Why does resetting one pointer to the head find the cycle entry?

The head-to-entry distance equals the meeting-point-to-entry distance modulo the cycle length, so both pointers reach the entry at the same time.

14

Practice problems

ProblemDifficultyWhat it trains
876. Middle of the Linked ListEasyBasic speeds.
141. Linked List CycleEasyDetection.
142. Linked List Cycle IIMediumEntry point.
19. Remove Nth Node From End of ListMediumFixed gap.
143. Reorder ListMediumMiddle, reverse, merge.
287. Find the Duplicate NumberMediumArray as a linked list.