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 → NoneAfter reversing it, the list should become:
None ← 1 ← 2 ← 3 ← 4
Result:
4 → 3 → 2 → 1 → NoneThe 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:
- Save the next node.
- Reverse the current node’s pointer.
- Move
prevone step forward. - Move
currone 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 prevDry Run
Let’s trace the algorithm using:
1 → 2 → 3 → NoneInitial State
prev = None
curr = 1Iteration 1
Save the next node.
nxt = 2Reverse the pointer.
1 → NoneMove the pointers.
prev = 1
curr = 2Iteration 2
Save the next node.
nxt = 3Reverse the pointer.
2 → 1 → NoneMove the pointers.
prev = 2
curr = 3Iteration 3
Save the next node.
nxt = NoneReverse the pointer.
3 → 2 → 1 → NoneMove the pointers.
prev = 3
curr = NoneThe loop ends because curr is None.
Return prev.
3 → 2 → 1 → NoneWhy This Works
At every iteration:
prevpoints to the already reversed portion of the list.currpoints to the node we’re currently processing.nxtensures 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 (
prev,curr, andnxt) 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.