Reversing a linked list is the "Hello World" of pointer manipulation. It's a fundamental skill that tests your ability to manage memory addresses and understand how data structures are wired together. Whether you do it iteratively or recursively, the core logic remains the same: flip the arrows. π
π§© The Problem
Given the
headof a singly linked list, reverse the list, and return the reversed list.
Example
Input: 1 -> 2 -> 3 -> 4 -> 5 -> NULL
Output: 5 -> 4 -> 3 -> 2 -> 1 -> NULL
π οΈ Approach 1: Iterative (The Pointer Dance)
The iterative solution is the most space-efficient and commonly used in production. We use three pointers to keep track of where we are, where we came from, and where weβre going next.
The Idea
We keep track of:
prev: The previous node (starts asNone).curr: The current node we are processing (starts ashead).next_node: A temporary pointer to save the next node before we break the link.
π Visualizing the Iterative Step (Dry Run)
For a list: 1 -> 2 -> 3 -> None
| Step | curr | curr.next (Action) | prev | next_node |
|---|---|---|---|---|
| Start | 1 |
2 |
None |
- |
| 1 | 1 |
Point to prev (None) |
1 |
2 |
| 2 | 2 |
Point to prev (1) |
2 |
3 |
| 3 | 3 |
Point to prev (2) |
3 |
None |
Final Result: 3 -> 2 -> 1 -> None
π» Iterative Code
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
prev = None
curr = head
while curr:
next_node = curr.next # 1. Save the next node
curr.next = prev # 2. Reverse the link (flip the arrow)
prev = curr # 3. Move 'prev' one step forward
curr = next_node # 4. Move 'curr' one step forward
return prevπ οΈ Approach 2: Recursive (The Leap of Faith)
The recursive approach is elegant but uses more space on the call stack. The "trick" here is to reverse the rest of the list first, then fix the current node's pointer.
The Idea
If we have 1 -> 2 -> 3, we call the function on 2 -> 3.
- It returns the reversed sub-list:
3 -> 2. - Now we need to make
2point back to1. - And make
1point toNone.
π» Recursive Code
class Solution(object):
def reverseList(self, head):
# Base case: empty list or single node
if not head or not head.next:
return head
# Reverse the rest of the list
new_head = self.reverseList(head.next)
# 'head.next' is still the node that was originally after 'head'
# We make THAT node point back to 'head'
head.next.next = head
# Break the old forward link
head.next = None
return new_headβ±οΈ Complexity Analysis
| Approach | Time Complexity | Space Complexity | Rating |
|---|---|---|---|
| Iterative | π Optimal | ||
| Recursive | π¨ Elegant but Stack-Heavy |
π§ How to Recognize This Pattern
Linked list problems often require reversing a portion or the whole list. You'll see this in:
- Palindrome Linked List: Reverse the second half to compare with the first.
- Reverse Nodes in k-Group: A more complex version of this problem.
- Reorder List: Reverse the second half and merge.
π― Interview Tips
- Edge Cases: Always handle
None(empty list) and a single node list. - Naming: Use clear names like
prev,curr, andnext_node. Don't just usep,c,n. - Drawing: If you get stuck during an interview, draw the nodes and arrows. It makes the pointer logic much harder to mess up.
