Linked lists are one of the most fundamental data structures, and reversing a linked list is a classic interview question. Although the problem is straightforward, it tests your understanding of pointers and how nodes are connected.

In this article, we’ll break down the problem, understand the intuition behind the solution, and walk through an efficient iterative approach.

Problem Statement

Given the head of a singly linked list, reverse the list and return the new head.

Example 1

Input

head = [0,1,2,3]

Output

[3,2,1,0]

Example 2

Input

head = []

Output

[]

Constraints

  • The number of nodes in the list is between 0 and 1000.
  • Each node value is between -1000 and 1000.

Understanding the Problem

A singly linked list only allows us to move forward because each node stores a reference to its next node.

For example:

1 → 2 → 3 → 4 → None

After reversing it, the list should become:

None ← 1 ← 2 ← 3 ← 4

Result:
4 → 3 → 2 → 1 → None

The challenge is that once you change a node’s next pointer, you lose access to the remaining nodes unless you’ve already saved that reference.


The Idea

We’ll keep track of three pointers:

  • prev → the previous node (initially None)
  • curr → the current node we’re processing
  • nxt → stores the next node before we modify any pointers

For every node:

  1. Save the next node.
  2. Reverse the current node’s pointer.
  3. Move prev one step forward.
  4. Move curr one step forward.

Repeat until we’ve processed every node.


Solution

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        prev, curr = None, head

        while curr:
            nxt = curr.next
            curr.next = prev
            prev = curr
            curr = nxt

        return prev

Dry Run

Let’s trace the algorithm using:

1 → 2 → 3 → None

Initial State

prev = None
curr = 1

Iteration 1

Save the next node.

nxt = 2

Reverse the pointer.

1 → None

Move the pointers.

prev = 1
curr = 2

Iteration 2

Save the next node.

nxt = 3

Reverse the pointer.

2 → 1 → None

Move the pointers.

prev = 2
curr = 3

Iteration 3

Save the next node.

nxt = None

Reverse the pointer.

3 → 2 → 1 → None

Move the pointers.

prev = 3
curr = None

The loop ends because curr is None.

Return prev.

3 → 2 → 1 → None

Why This Works

At every iteration:

  • prev points to the already reversed portion of the list.
  • curr points to the node we’re currently processing.
  • nxt ensures we don’t lose access to the remaining nodes before changing any pointers.

By the time we finish, every link has been reversed, and prev becomes the new head of the list.


Complexity Analysis

Time Complexity

O(n)

We visit each node exactly once.

Space Complexity

O(1)

We only use three pointers regardless of the list size.


Key Takeaways

  • Always save the next node before modifying any pointers.
  • Use three pointers (prevcurr, and nxt) to reverse the list safely.
  • The iterative solution is optimal with O(n) time and O(1) extra space.
  • This pattern is useful in many linked list problems, making it a must-know technique for coding interviews.

Final Thoughts

Reverse Linked List is one of the first linked list problems every programmer encounters, and for good reason. It teaches you how pointer manipulation works without requiring extra memory. Once you’re comfortable with this pattern, you’ll find it much easier to solve more advanced linked list problems such as reversing a sublist, reversing nodes in groups, or checking if a linked list is a palindrome.

Master this technique—it appears frequently in coding interviews and forms the foundation for many other linked list algorithms.