March 24
Reverse Linked List
How to move away from rebuilding with an array and understand the core pointer idea in a linked list.
Linked List Beginner 15 min TypeScript
Given the head of a linked list, reverse the list and return the new head.
Example:
Input: 1 -> 2 -> 3 -> 4 -> 5 -> null
Output: 5 -> 4 -> 3 -> 2 -> 1 -> null
What to notice before coding
- You return the new head of the reversed list.
- The challenge is changing pointer direction without losing the rest of the list.
- An empty list and a single-node list are still valid cases.
Common mistakes
- overwriting `current.next` before saving the next node
- returning `head` instead of the new head at the end
Step 1 — Understand what changes in a linked list
In an array, reversing usually means swapping positions.
In a linked list, the values do not even need to change.
What changes is the next pointer.
The whole problem is about that:
- who points to whom now
- how to change that without losing the rest of the list
Step 2 — Write a correct baseline
A simple baseline is to store the values in an array and rebuild a new list backward:
export function reverseList(head) {
const values = []
let current = head
while (current) {
values.push(current.val)
current = current.next
}
let newHead = null
for (const value of values) {
newHead = { val: value, next: newHead }
}
return newHead
}
It works. But it creates a new structure and avoids the real point of the problem.
Step 3 — Ask what needs to happen at each node
When you are at current, you want to reverse the arrow:
- before:
current -> next - after:
current -> previous
But if you do that carelessly, you lose the rest of the list.
So the safe order is:
- save
nextNode - reverse
current.next - move the pointers forward
Step 4 — Walk with three references
The three references are:
previouscurrentnextNode
At the end, previous becomes the new head.
The interactive editor needs JavaScript. You can still read the prompt and copy the starter code below.
Starter code
export function reverseList(head) {
// head is an object like { val: number, next: ... } or null
// your solution here
return head
}
Haven't solved it yet?
Viewing the solution now may reduce learning. It's worth trying a bit more.
Open the reference solution
Without JavaScript, the reference solution is shown inline instead of in a dialog.
Solution
Final complexity
Time: O(n)
Space: O(1)
Solution 1 — Rebuild with array O(n) extra space
Good baseline for understanding.
export function reverseList(head) {
const values = []
let current = head
while (current) {
values.push(current.val)
current = current.next
}
let newHead = null
for (const value of values) {
newHead = { val: value, next: newHead }
}
return newHead
}
Correct, but it does not train the main linked-list skill.
Solution 2 — In-place pointers O(1) extra space
Now the idea is to reverse the pointers during one pass.
export function reverseList(head) {
let previous = null
let current = head
while (current) {
const nextNode = current.next
current.next = previous
previous = current
current = nextNode
}
return previous
}
The algorithm looks short, but it only works because the order of steps protects the part of the list that still needs processing.
What to say in the interview
A strong short explanation would be:
The baseline can rebuild the list with an array, but the stronger solution reverses the pointers in place. At each node I save the next node, set
current.next = previous, and then move forward. At the end,previousbecomes the new head withO(1)extra space.
That shows that you:
- understand the difference between arrays and linked lists
- can manipulate pointers without losing references
- can explain the order of operations clearly
When this pattern shows up again
The same pattern comes back when you need to:
- relink nodes
- walk a list while carrying previous state
- change pointer direction
- solve linked-list problems without extra memory
The point is not memorizing
reverseList.
The point is learning to control references without getting lost.