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.