Algorithm

Reverse Linked List

Linked List Pattern

Reverse Linked List

Given the head of a singly linked list, reverse it so the original last node becomes the head and every next pointer points the opposite way, then return the new head. Rewire the existing nodes in place — no new list is built. An empty list returns null; a single-node list returns itself unchanged.

CONSTRAINTS
  • The number of nodes in the list is in the range [0, 5000]
  • -5000 <= Node.val <= 5000
EXAMPLE 1
Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]
Every link is flipped, so the order is exactly reversed: the original tail 5 is now first and the original head 1 is now last.
EXAMPLE 2
Input: head = [1]
Output: [1]
A single node has nothing after it to reorder, so the reversed list is identical to the original.
EXAMPLE 3
Input: head = []
Output: []
An empty list has no nodes to reverse; the result is empty (null).
How should empty or single-node lists behave?
Both return unchanged — an empty list returns null, a one-node list returns that node. A correct pointer solution handles both automatically without special-casing them.
Am I reversing the actual nodes or just their values?
Reverse the nodes by rewiring next pointers; don't swap values. Pointer rewiring is O(1) per node, preserves node identity, and is the skill the problem is testing.
Is a recursive solution acceptable?
It's correct but uses O(N) stack space, one frame per node, which can overflow on long lists. The iterative three-pointer version is O(1) space and is the expected answer when memory matters.
Would a doubly linked list change the approach?
It makes reversal conceptually easier since each node already knows its predecessor, but the singly linked case — carrying prev yourself — is the standard interview version and the transferable technique.
The Three-Pointer Pivot

Reversing a linked list is the art of flipping every arrow in the chain to point backward. The challenge is doing this without "breaking" the chain. If you flip a link before caching where the next node was, the rest of the list becomes unreachable in memory.

Sliding Windows

We maintain a small window of three pointers that slide across the list:
1. Prev: The part of the list we have already reversed.
2. Curr: The node we are currently "flipping."
3. Next: A temporary cache of the unvisited part of the list.

python
prev = None
curr = head

while curr:
    # 1. Cache the next node
    next_temp = curr.next
    
    # 2. FLIP: Point current backward
    curr.next = prev
    
    # 3. SLIDE: Move window forward
    prev = curr
    curr = next_temp

return prev # New head
Efficiency: O(1) Space

This iterative approach is the professional standard as it uses zero extra memory, unlike recursive solutions which consume space on the call stack.

Worked Example:[1, 2, 3]
1
curr
2
next
3
NULL
We initialize our tracker pointer 'curr' at the head node containing 1 and cache the next node 'next' at 2.
1
prev
2
curr
3
next
NULL
We point node 1 backward to prev (null). We then slide our pointers forward: 'prev' moves to 1, 'curr' moves to 2, and we cache the next node 'next' at 3.
1
2
prev
3
curr
NULL
We point node 2 backward to prev (1). We slide pointers forward: 'prev' moves to 2, 'curr' moves to 3. Since there are no nodes after 3, 'next' becomes null.
1
2
3
prev
NULL
We point node 3 backward to prev (2). 'curr' becomes null, and we return 'prev' (3) as our new head node.
Interactive Strategy Visualization

Iterative Reversal

Strategy: 3-Pointer Window
Efficiency: O(1) Space
CURR1NEXT23
Operationprev = null, curr = head
Memory [prev]
null
1. Initialization
Pointers set: 'curr' at head, 'prev' is null.
O(N) Time · O(N) Space Recursion/Stack
O(N) Time · O(1) Space Three-Pointer Rewire