LearnDSA Patterns

Pattern #5 · Linked List · O(N) Time O(1) Space

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.

🔁 prev · curr · temp ♻️ Zero extra memory 🧩 Sublist & k-group variants
Scroll to learn

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.

A
B prev
C curr
D temp
E

🚀

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.

A B C D E prev curr

Initial state: prev=null, curr=A. List: A→B→C→D→E→null.

prev curr original link reversed link
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

🔁 Recursive Approach O(N) space
Reverse list Recurse to the tail, rewire on the way back
Memory usage O(N) — one stack frame per node
Code clarity Very short, but harder to trace by hand
Large lists Risk of stack overflow at deep recursion
Interviews Good to mention, rarely the final answer
📍 Iterative (prev/curr/temp) O(1) space
Reverse list Walk once, flip each link as you go
Memory usage O(1) — three pointer variables, always
Code clarity Explicit steps, easy to hand-trace
Large lists No recursion, no stack-depth limit
Interviews Preferred optimal solution

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 study
M2 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

Question 1 of 12 Score: 0
The iterative in-place reversal uses three variables — prev, head, and temp. What role does temp play? basic

Keep Learning

You've mastered In-Place Reversal 🎉

This pattern unlocks sublist reversal, k-group reversal, and palindrome checks — all in O(1) space.