Given the head of a singly linked list, reverse the list and return the head of the reversed list.
A singly linked list is a chain of nodes where each node holds a value and a single next pointer to the node that follows it. Reversing the list means the node that was last becomes the new head, and every next pointer is flipped to point at what used to come before it.
You are given only the head pointer — there are no prev pointers and no size field. Return the head of the list after the direction of every link has been reversed.
O(1) extra space.null (or the language's nil/None). With head empty, the loop never runs and prev stays null, which is exactly correct — no special case needed.curr.next = prev overwrites the only reference to the rest of the list. Saving nxt = curr.next first preserves your path forward.head.next.next = head and head.next = null. It's elegant but uses O(n) stack space, which can overflow on very long lists — mention that trade-off.m-1, then apply the same three-pointer flip n-m times to reverse just that segment, and carefully reconnect the segment's ends to the surrounding list.Input: head = [1,2,3,4,5] Output: [5,4,3,2,1] Every next pointer is flipped, so the tail 5 becomes the new head.
Input: head = [1,2] Output: [2,1]
Input: head = [] Output: [] An empty list reversed is still empty.
- The number of nodes in the list is in the range [0, 5000]. - -5000 <= Node.val <= 5000
Reversing a linked list is the hello world of pointer manipulation — the moment you truly understand it, every list problem gets easier. The trick is that you only ever hold the head, so you must flip the arrows one at a time without losing your place.
next neighbor.next reference points at without copying the node itself.curr.next, the rest of the list is gone unless you saved it first.In plain words: walk the list once, and for each node, make its next point at the node you just came from instead of the node ahead. Formally, if the list is a → b → c → null, you must return c → b → a → null.
Worked example — head = [1,2,3]
start: 1 → 2 → 3 → null flip 1: null ← 1 2 → 3 → null (prev=1, curr=2) flip 2: null ← 1 ← 2 3 → null (prev=2, curr=3) flip 3: null ← 1 ← 2 ← 3 (prev=3, curr=null) return prev = 3 → 3 → 2 → 1 → null
Asking one or two sharp questions before touching the keyboard shows you think about the shape of the input, not just the happy path.
“Can the list be empty, and can it have a single node?”
Both are valid here — the code must return null/the same node without crashing on a next dereference.
“How long can the list get?”
Up to 5000 nodes, so an O(n) single pass is plenty — but a deep recursive solution risks a stack overflow, which nudges toward the iterative approach.
“Should I reverse in place or may I build a new list?”
In place with O(1) extra space is the expected, elegant answer; rebuilding is fine to explain the idea but uses O(n) memory.
Before I start, a couple of quick clarifications.
First — I'll assume the list can be empty or a single node, and handle those without special-casing beyond the loop.
And I'll aim for an in-place reversal in one pass with O(1) extra space, which I think is the cleanest solution here.
The instant you do curr.next = prev, the original link to the rest of the list is destroyed. So the very first line of the loop body has to stash nxt = curr.next. This single line is what makes the whole thing work.
You never need the whole list in memory. prev (the reversed part built so far), curr (the node you're flipping), and nxt (the untouched rest) fully describe the state. Slide all three forward each step.
... ← prev curr → nxt → ...
flip: curr.next = prev
then: prev = curr, curr = nxtWhen curr walks off the end and becomes null, prev is sitting on the old tail — which is exactly the new head. No extra bookkeeping needed: just return prev.
| Copy to array | In-place pointers | |
|---|---|---|
| Time | O(n) | O(n) |
| Space | O(n) | O(1) |
| Passes | Two | One |
Both are linear in time, but the in-place three-pointer walk needs no extra storage and finishes in a single sweep. See the full code for each in the Approaches selector below.
Key takeaway
To reverse a singly linked list, walk it once carrying three pointers — prev, curr, nxt — and flip each next to point backward. Always save the next node before you overwrite the link. Return prev.
prev = null
curr = head
while curr is not null:
nxt = curr.next # save the rest first
curr.next = prev # flip the arrow
prev = curr # advance the built part
curr = nxt # advance the cursor
return prev