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.