Home / Patterns / Lesson 4

Fast & Slow Pointers — Cycles and Middles

Medium ⏱ 5 min read 🧩 Pattern 4 of 16

Two pointers moving at different speeds through a linked structure. Simple trick, elegant results — and a guaranteed linked-list interview topic.

Find the middle in one pass

function middle(head) {
  let slow = head, fast = head;
  while (fast && fast.next) {
    slow = slow.next;        // 1 step
    fast = fast.next.next;   // 2 steps
  }
  return slow;               // when fast hits the end, slow is at the middle
}

No counting, no second pass. Fast covers 2x distance, so when it finishes, slow is halfway.

Detect a cycle (Floyd's algorithm)

function hasCycle(head) {
  let slow = head, fast = head;
  while (fast && fast.next) {
    slow = slow.next;
    fast = fast.next.next;
    if (slow === fast) return true;   // they met inside the loop
  }
  return false;                        // fast reached the end → no cycle
}

Why they must meet: once both are inside the cycle, the gap between them shrinks by exactly 1 each step (fast gains 1 per tick). A shrinking gap on a closed loop always reaches 0. That one-sentence proof impresses interviewers.

Why not just use a Set?

You can — store visited nodes, O(n) space. Fast/slow does it in O(1) space, and "can you do it without extra memory?" is precisely the follow-up they ask.

Spot it when…

  • Linked list + cycle / loop-start / middle / "is it a palindrome" (middle + reverse half).
  • Arrays acting as linked structures (value = next index) — e.g. duplicate-number problems.

Practice the foundation

Fast/slow builds on pointer manipulation — make sure Reverse a Linked List is effortless first, then combine: "reorder list" = middle (fast/slow) + reverse + merge. Pattern stacking is exactly how medium problems are built.