ESC

Type to search the knowledge base.

Reverse Linked List

Reverse a singly linked list in place — iterative three-pointer walk, recursive version, and the interview follow-ups.

beginner4 min read
  • dsa
  • linked-list
  • interview
  • Google
  • Meta
  • Amazon
  • Microsoft
  • Uber

The problem

Given the head of a singly linked list, reverse the list and return the new head.

Input:  1 → 2 → 3 → 4 → 5 → null
Output: 5 → 4 → 3 → 2 → 1 → null

Input:  null
Output: null

Input:  1 → null
Output: 1 → null

Constraints you should restate: nodes are typical { val, next }; list may be empty; do it in O(1) extra space if asked for in-place.

Why it shows up: pointer rewiring under pressure. Frontend cousins — undo stacks of list nodes, reverse of a playlist queue, interview warm-ups before harder list problems (cycle, reorder, reverse k-group).

Node shape

class ListNode {
  val: number;
  next: ListNode | null;
  constructor(val = 0, next: ListNode | null = null) {
    this.val = val;
    this.next = next;
  }
}

Brute force (mention, then skip)

Walk the list into an array, reverse the array, rebuild nodes. Correct, O(n) space, looks like you panicked. Say it in one sentence and move on.

Optimal: iterative three pointers

Keep prev, curr, and next (or save curr.next before you overwrite it).

  1. prev = null, curr = head
  2. While curr:
    • save next = curr.next
    • curr.next = prev
    • advance prev = curr, curr = next
  3. Return prev (new head)
function reverseList(head: ListNode | null): ListNode | null {
  let prev: ListNode | null = null;
  let curr = head;

  while (curr) {
    const next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }

  return prev;
}
Time O(n)
Space O(1)

Walk 1 → 2 → 3

step prev curr list shape
start null 1 1→2→3
after 1 1 2 1→null, 2→3
after 2 2 3 2→1→null, 3→null pending
after 3 3 null 3→2→1→null

Recursive version (know it)

Reverse the rest, then make the next node point back at you, and cut your forward link.

function reverseListRecursive(head: ListNode | null): ListNode | null {
  if (!head || !head.next) return head;

  const newHead = reverseListRecursive(head.next);
  head.next.next = head;
  head.next = null;
  return newHead;
}
Time O(n)
Space O(n) call stack

Prefer iterative in interviews unless they ask for recursion or stack-depth discussion.

Edge cases to say out loud

  • Empty list → return null
  • Single node → return same node
  • Two nodes — classic off-by-one zone; dry-run once
  • Do not lose the rest of the list: always save next before rewiring
  • Cycle? Classic problem assumes acyclic; if input may cycle, detect first

Common bugs

  • Forgetting to save next → infinite loop or lost tail
  • Returning head instead of prev
  • Leaving the old head’s next pointing into the old chain (recursive: forget head.next = null)
  • Mutating values instead of pointers (works for numbers only; wrong skill)

Follow-ups

  1. Reverse Linked List II — reverse between left and right indices
  2. Reverse Nodes in k-Group — hard; group-wise reverse
  3. Palindrome Linked List — reverse second half, compare
  4. Reorder List — split, reverse second half, merge

Interview delivery

  1. Clarify singly vs doubly, empty list, in-place.
  2. Draw three nodes; name prev / curr / next.
  3. Code iterative cleanly.
  4. Trace one example.
  5. State O(n) time, O(1) space.
  6. Offer recursive if they want.

Further reading