Lesson 30 of 30
The classic pointer-juggling problem, slowed all the way down — both the iterative version and the recursive 'leap of faith' version.
14 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Picture a scavenger hunt where each clue points to the next location — clue 1 says "go to the park," and at the park is clue 2 saying "go to the library." That chain of clues, each pointing forward, is a linked list. Reversing it means making every clue point backward instead — the library's clue now points to the park, and the park's clue points to nothing, because it's the new end.
This is one of the most famously confusing beginner problems in the field, not because the idea is hard, but because you have to change several arrows without losing track of the rest of the chain. If you've ever felt your brain "lose the thread" doing this on paper, that's completely normal — it happens to nearly everyone the first several times.
We'll do this twice: first iteratively, moving one pointer at a time. Then recursively, using the "leap of faith" idea from earlier in this track — trusting a smaller version of the same problem is already solved, and figuring out only what needs to happen at this one step.
// A node in the chain: it holds a value and points to the next node.
function makeNode(value, next = null) {
return { value, next };
}
// ITERATIVE version — walk the chain once, flipping each arrow as
// we go. The tricky part: once you flip an arrow, you lose the way
// forward, unless you save it FIRST.
function reverseIterative(head) {
let prev = null; // what the current node should now point to
let current = head; // the node we're currently flipping
while (current !== null) {
const next = current.next; // save the rest of the chain BEFORE we break the link
current.next = prev; // flip this node's arrow backward
prev = current; // move prev forward to where we just were
current = next; // move current forward to the node we saved
}
return prev; // prev now sits on the old last node — the new head
}
// RECURSIVE version — the "leap of faith": assume reverseRecursive
// already correctly reverses everything AFTER this node. We only
// have to figure out what THIS node needs to do.
function reverseRecursive(head) {
if (head === null || head.next === null) {
return head; // an empty or one-node chain is already "reversed"
}
const newHead = reverseRecursive(head.next); // trust this reverses the rest
head.next.next = head; // the node right after us now points back to us
head.next = null; // we become the new end, so we point to nothing
return newHead; // the new head never changes as we unwind
}
current.next = prev before saving current.next into a variable, you've permanently lost the rest of the chain. Always save first.next to null in the recursive version. Without it, the old first node still points forward into the now-reversed chain, quietly creating a loop.The iterative version is pointer manipulation on a linked list, the structure from earlier in this track. The recursive version leans entirely on the "leap of faith" framing — trust the smaller version of the problem is already solved, and only handle what's new at your step.