Linked List Reversal
The Intuition
You have a chain of paper clips linked together. You want to reverse the chain. Here's what you do: hold the first clip, unhook it from the second, and set it aside to start a new chain. Now pick up the second clip, unhook it from the third, and attach it before the first clip in your new chain. Keep going. Every clip you detach gets placed at the front of the new chain.
When you're done, the clip you picked up last is at the front, and the clip you picked up first is at the back. Reversed.
In code, you need three pointers to pull this off. current is the clip you're about to detach. prev is the growing reversed chain behind you. And you need to save next before you break the link, because once you point current.next to prev, you've lost your reference to the rest of the original chain. Save it, break it, move on. That's the entire loop: save next, reverse the pointer, advance both prev and current one step forward.
Reversing entire or partial linked lists, checking palindromes, reordering nodes, or any problem requiring reversed traversal of a singly linked list.
- Need random access by index (use array)
- Need to reverse based on values not position (use sorting)
- Circular linked list without clear start/end
- empty list
- single node
- two nodes
Key Points
- •Use three pointers: prev, current, next
- •Save next before breaking the link
- •Iterative approach is preferred for O(1) space
- •For partial reversal, track the node before the segment
- •Recursive approach uses O(n) call stack space
Code Template
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverse_list(head):
"""Reverse entire linked list iteratively."""
prev = None
current = head
while current:
next_node = current.next
current.next = prev
prev = current
current = next_node
return prev
def reverse_between(head, left, right):
"""Reverse nodes from position left to right (1-indexed)."""
dummy = ListNode(0, head)
prev = dummy
for _ in range(left - 1):
prev = prev.next
current = prev.next
for _ in range(right - left):
next_node = current.next
current.next = next_node.next
next_node.next = prev.next
prev.next = next_node
return dummy.nextCommon Mistakes
- Losing reference to the next node before reassigning
- Not returning the new head (previously the tail)
- Off-by-one when reversing a sub-section of the list