Reversing a linked list
The three-pointer dance, in a loop and in recursion — and why it is asked so often.
Reversal is the standard interview warm-up because it tests exactly one thing: can you move pointers without losing the list.
Iterative — the version to know cold
function reverse(head) {
let previous = null;
let current = head;
while (current) {
const next = current.next; // 1. save what comes after
current.next = previous; // 2. flip this link backwards
previous = current; // 3. step both pointers forward
current = next;
}
return previous; // the old tail is the new head
}
Four lines in a fixed order. Swap lines 1 and 2 and the rest of the list is unreachable — that single mistake is what the question is really probing.
O(n) time, O(1) space, and it returns previous, not current, because the loop ends with current === null.
Recursive
function reverseRecursive(head) {
if (!head || !head.next) return head; // empty or single node
const newHead = reverseRecursive(head.next);
head.next.next = head; // the node ahead points back at me
head.next = null; // and I now end the list
return newHead; // unchanged all the way up
}
Same O(n) time but O(n) stack space — a real risk on long lists. The line head.next.next = head is worth reading twice: after the recursive call, head.next is the tail of the reversed remainder, so pointing its next at head appends head to the end.
The variations you will be asked next
- Reverse between positions m and n. Dummy head, walk to m−1, reverse exactly n−m+1 links, reconnect both ends.
- Reverse in groups of k. Check that k nodes remain, reverse them, then recurse on the rest.
- Palindrome check. Find the middle with fast and slow pointers, reverse the second half, compare, then restore.
That last one shows the pattern's real value: reversal in O(1) space is what lets you compare a list against itself without copying it into an array.
Restore the list before returning if the caller still owns it — leaving it half-reversed is a bug an interviewer will look for.