Learn › DSA Patterns
In-Place Linked List
Reversal
Flip every pointer in a linked list using only three variables — no stack, no array — in O(N) time, O(1) space.
Story Time
The Conga Line Turnaround 💃🕺
Before writing a single line of code, let's understand the intuition through a story.
The Line Forms
A conga line of dancers forms, each one holding the shoulders of the person ahead of them: A→B→C→D→E. The DJ shouts a new rule: "Now the line must face the other way — but nobody can leave the room to form a new line!"
One Dancer at a Time
Dancer A turns around first — but before letting go of the person ahead, A quietly remembers who was next in line (that's the only way to still find B once A lets go). Then A turns to face backward. There's nobody behind A yet, so A now holds onto nothing — a dead end, which is exactly what the new last position should be.
The Wise Coder's Insight
A wise coder watching nearby explains: "Each dancer needs exactly three things in mind: who was behind me a moment ago (so I can turn to face them), who is still ahead of me in the original line (so I don't lose the rest of the line), and myself right now." Move down the line once, and by the time you reach the end, everyone faces backward.
- ✗ Forget who's still ahead → the rest of the line is lost the moment you let go.
- ✓ Save it first, then turn → nobody is ever lost, one pass, zero extra space.
Visualising the Pointers
Mid-reversal on A→B→C→D→E: everything left of curr already
faces backward, everything from curr onward still faces forward.
🚀
Moral of the story
Three pointers, one pass. Save what's ahead, flip the link, step both trackers forward — in O(N) time using only O(1) extra space. No stack, no array!
Interactive
Reversal Visualizer
Watch prev, curr, and temp flip every link, one node at a time.
Initial state: prev=null, curr=A. List: A→B→C→D→E→null.
temp = curr.next Save the rest of the list curr.next = prev Flip this node's link prev, curr = curr, temp Advance both pointers Complexity
Three Approaches
| Approach | Time | Space | Best for |
|---|---|---|---|
| Stack / Array | O(N) | O(N) | Simple, readable |
| Iterative (3 pointers) Preferred ✓ | O(N) | O(1) | Memory-constrained, most interviews |
| Recursive | O(N) | O(N) | Elegant, but stack-depth risk on huge lists |
The recursive version reads beautifully, but every call adds a stack frame — O(N) space hiding behind O(N) time. The iterative three-pointer version gets the same result with zero extra memory.
TypeScript
Implementation
Three variations, from the essential loop to a real LeetCode variant.
// O(N) time, O(1) space — three pointers, one pass
class ListNode {
value: number;
next: ListNode | null;
constructor(value: number, next: ListNode | null = null) {
this.value = value;
this.next = next;
}
}
function reverseList(head: ListNode | null): ListNode | null {
let prev = null; // will become the new head
while (head) {
const temp = head.next; // 1. save the rest of the list first
head.next = prev; // 2. reverse the current link
prev = head; // 3. advance prev forward
head = temp; // 4. advance head forward
}
return prev; // head is null here — prev holds the answer
}
// 1→2→3→null becomes 3→2→1→null
console.log(reverseList(list)?.value); // → 3 Want the full debugging story behind this technique? Read the Reverse Linked List case study.
Comparison
Iterative vs Recursive
Practice
Solve It Yourself
Click any question to see hints and approach.
B Basic
B1 What is the In-Place Linked List Reversal technique, and why is it useful? ⌄
💡 Hint
Think about what has to happen to every arrow in the list, and how many extra variables you actually need to track while doing it.
✅ Answer
Walk the list once, flipping each node's .next pointer to point at the previous node instead of the next one, using three tracking variables (prev, curr, temp). Key benefit: O(1) space — no stack, no array, no copy of the list needed.
B2 Given list 1→2→3→null, trace reverseList() step by step. What is the final list? ⌄
💡 Hint
Track prev, head (curr), and temp on each iteration. The loop exits when head becomes null.
✅ Answer
iter1: prev=null→1, head becomes 2. iter2: prev=1→2 (2.next=1), head becomes 3. iter3: prev=2→3 (3.next=2), head becomes null → loop exits. Return prev = node 3. Final list: 3→2→1→null.
B3 Why does reverseList(null) (an empty list) correctly return null with no special-casing? ⌄
💡 Hint
Check what prev is initialized to, and whether the while loop condition ever lets the body run at all.
✅ Answer
prev starts as null, and while (head) is false immediately since head is already null — the loop body never executes. The function falls straight through to return prev, which is still null: the correct answer for an empty list.
M Intermediate
M1 LeetCode 206 — Reverse Linked List: given [1,2,3,4,5], what's the reversed list? ⌄
💡 Hint
Trace prev/head/temp through all five nodes. Watch what happens to prev on the very last iteration.
✅ Answer
[5,4,3,2,1]. This exact problem has a full worked debugging journey (four real bugs found and fixed, not just the final answer) on the case study page.
→ Read the full case studyM2 LeetCode 92 — Reverse Linked List II: given [1,2,3,4,5], left=2, right=4, what's the result? ⌄
💡 Hint
Only nodes 2 through 4 get reversed. The nodes before and after the sublist keep their original positions, just reconnected to the new sublist ends.
✅ Answer
[1,4,3,2,5]. Nodes 2,3,4 reverse in place to 4,3,2; node 1 now points to 4, and node 2 (the old sublist head) now points to 5.
→ Solve on LeetCode ↗M3 LeetCode 25 — Reverse Nodes in k-Group: given [1,2,3,4,5], k=2, what's the result? ⌄
💡 Hint
Reverse each full group of k nodes; a trailing group with fewer than k nodes is left as-is.
✅ Answer
[2,1,4,3,5]. Groups [1,2] and [3,4] each fully reverse; node 5 is a leftover group of size 1 (< k) and stays untouched.
→ Solve on LeetCode ↗H Advanced
H1 LeetCode 234 — Palindrome Linked List: how does in-place reversal help solve this in O(1) space? ⌄
💡 Hint
Find the middle (fast/slow pointers), reverse the second half in place, then compare both halves.
✅ Answer
Find the middle, reverse the second half using this exact prev/curr/temp technique, then walk both halves comparing values. No array copy needed — reversal turns a two-directional comparison problem into two forward walks.
→ Solve on LeetCode ↗H2 How would you reverse a doubly linked list in place, and how does it differ from the singly-linked version? ⌄
💡 Hint
A doubly linked node has both .next and .prev. What has to happen to both fields for every node?
✅ Answer
For each node, swap its .next and .prev fields, then move to what is now its .prev (the original .next). No temp variable for 'the rest of the list' is needed — the .prev field already holds it. Finally, swap head and tail.
H3 Reverse Linked List II (LC 92) requires reconnecting the reversed sublist to the untouched parts. What's the general strategy for that reconnection? ⌄
💡 Hint
Use a dummy node to handle 'left = 1' cleanly, and keep a reference to the node just before the sublist and the sublist's original head (which becomes its new tail).
✅ Answer
Keep 'before' (node just before the sublist) and let the sublist's original head become its new tail after reversal. Reconnect: before.next = new sublist head (the old prev), and the old sublist head (now tail) .next = the node right after the sublist (curr, once the inner loop ends).
→ Solve on LeetCode ↗H4 Why is stack-depth a real concern for the recursive version on very long lists, and how would you estimate a safe limit? ⌄
💡 Hint
Each recursive call adds one frame to the call stack before any unwinding happens. Most runtimes have a fixed maximum call-stack size.
✅ Answer
The recursive version recurses all the way to the tail before doing any work, so it needs N stack frames for a list of N nodes. JavaScript engines typically allow roughly 10,000–15,000 stack frames before a 'Maximum call stack size exceeded' error — lists longer than that need the iterative version.
In the Wild
Real-World Applications
Browser Navigation
Back/Forward History
Some browser history implementations model visited pages as a linked chain. Reversing a segment in place lets 'jump to page N steps back' work without duplicating the whole history into a new structure.
🔁 How it fits: History entries as nodes, navigation order as the pointer. In-place reversal replays a segment backward with zero extra memory.
Undo/Redo Systems
Command History Reversal
Editors that chain undo commands as a linked list can reverse a range of them in place to replay actions in the opposite order, without allocating a parallel redo list.
🔁 How it fits: Each edit action links to the next. Reversing a sublist flips exactly the commands being replayed — the rest of the history stays untouched.
Music / Video Players
Reverse Playback Queue
A 'play in reverse' feature on a linked queue of tracks can flip the direction of the whole queue in place, avoiding a second copy of the playlist for the reverse mode.
🔁 How it fits: Tracks as nodes, next-track as the pointer. O(1) space reversal works even on memory-constrained embedded players.
Compilers & Linkers
Reversing Instruction Chains
Some intermediate-representation passes build instruction chains in reverse order for analysis, then need to flip them back to forward order before code generation — in place, without extra allocation.
🔁 How it fits: Instructions as nodes linked by execution order. In-place reversal avoids doubling memory for large compilation units.
Quick Reference
Cheat Sheet
The Steps
1. Save
temp = head.next 2. Reverse
head.next = prev 3. Advance prev
prev = head 4. Advance head
head = temp When to Use
- ✓ Reverse an entire linked list
- ✓ Reverse a sublist between two positions
- ✓ Reverse nodes in groups of k
- ✓ Check palindrome linked list
- ✓ Reverse the second half after finding the middle
- ✓ Rotate or reorder a list without extra memory
Pattern Variations
Full Reversal
reverseList() → return new head
Sublist Reversal
reverseBetween() → stitch boundaries
Complexity
Time: O(N)
Space: O(1)
Test Yourself
Quiz: Check Your Understanding
Your score
0 / 12
Keep Learning
You've mastered In-Place Reversal 🎉
This pattern unlocks sublist reversal, k-group reversal, and palindrome checks — all in O(1) space.