Skip to main content

Reverse Linked List

How to move away from rebuilding with an array and understand the core pointer idea in a linked list.

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

Common mistakes

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:

  1. save nextNode
  2. reverse current.next
  3. move the pointers forward

Step 4 — Walk with three references

The three references are:

  • previous
  • current
  • nextNode

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
}
solution.ts
Stuck? Hints available.

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, previous becomes the new head with O(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.

Next challenge Merge Two Sorted Lists Previous challenge Binary Search

Related challenges

Related articles