Three-Pointer Iterative Reverse Runs in O(n) Time and O(1) Space
Reverse a Linked List
Master in-place linked list reversal with the classic three-pointer iterative algorithm and its elegant recursive counterpart.
What you'll learn
- Reverse a singly linked list in-place using prev, curr, and next pointers
- Implement the recursive reversal and understand its O(n) call-stack cost
- Identify when iterative reversal is preferred over the recursive version
Reversing a linked list means flipping every next pointer so the former
tail becomes the new head. The challenge is doing it in place without
losing your position in the list.
Node Class
class ListNode {
constructor(val = 0, next = null) {
this.val = val;
this.next = next;
}
} Iterative Three-Pointer Approach
Keep three variables as you walk the list:
prev— the node that should followcurrafter reversal (startsnull)curr— the node being processed right nownext— a temporary save ofcurr.nextbefore it is overwritten
function reverseList(head) {
let prev = null;
let curr = head;
while (curr !== null) {
const next = curr.next; // 1. save next
curr.next = prev; // 2. flip pointer
prev = curr; // 3. advance prev
curr = next; // 4. advance curr
}
return prev; // prev is the new head when curr reaches null
}
// Example
// Before: 1 → 2 → 3 → null
// After: 3 → 2 → 1 → null Walk through a three-node list to build intuition:
| Step | prev | curr | curr.next (after flip) |
|---|---|---|---|
| start | null | 1 | — |
| 1 | 1 | 2 | 1 |
| 2 | 2 | 3 | 2 |
| 3 | 3 | null | — |
When the loop ends prev points to the old tail — the new head.
Recursive Approach
The recursive version trusts the call stack to “remember” the suffix while it reverses the suffix and then splices the current node at the back.
function reverseListRecursive(head) {
// Base case: empty list or single node
if (head === null || head.next === null) return head;
// Reverse the rest of the list
const newHead = reverseListRecursive(head.next);
// head.next still points to the last node of the reversed suffix;
// make that node point back at head, then cut head's forward link.
head.next.next = head;
head.next = null;
return newHead;
} Recursion is elegant but uses O(n) call-stack frames. For very long lists this can cause a stack overflow in JavaScript; the iterative version is safer in production.
Complexity
| Approach | Time | Space |
|---|---|---|
| Iterative | O(n) | O(1) |
| Recursive | O(n) | O(n) call stack |
Practical Use
Reversal is a building block for many harder problems: reversing a sub-list, checking if a linked list is a palindrome, and reordering lists all rely on the same three-pointer technique.
Up Next
Learn Floyd’s tortoise and hare algorithm for detecting cycles in a linked list — and for finding exactly where the cycle starts.
Cycle Detection →