6 questions using this pattern
Reverse linked list nodes in-place by manipulating pointers without allocating extra space. This technique uses three pointers to track the previous, current, and next nodes while systematically reversing the direction of links.
Imagine a conga line where everyone faces forward. To reverse it, you don't rearrange people—you have each person turn around and grab the shoulders of whoever was behind them. You process one person at a time: they turn around, the next person steps forward, and so on until everyone faces the opposite direction.
Another analogy: reversing a chain of paper clips. You unclip each one from its forward neighbor and clip it to its backward neighbor, working through the chain.
Linked list reversal uses three pointers moving through the list:
At each step:
curr.next in next (before we lose it)curr.next = prevprev = curr, curr = nextThe key insight is that we're not moving nodes—we're redirecting pointers. This achieves O(n) time with O(1) space.
For partial reversal (reversing between positions m and n), we:
def reverse_list(head): prev = None curr = head while curr: next_node = curr.next curr.next = prev prev = curr curr = next_node return prevWe have a linked list: 1 → 2 → 3 → 4 → null. Reverse it to get 4 → 3 → 2 → 1 → null.
Full list reversal:
Initial: 1 → 2 → 3 → 4 → null
prev=null, curr=1
Step 1: Save next=2, reverse 1's link
null ← 1 2 → 3 → 4
prev curr
Step 2: Save next=3, reverse 2's link
null ← 1 ← 2 3 → 4
prev curr
Step 3: Save next=4, reverse 3's link
null ← 1 ← 2 ← 3 4
prev curr
Step 4: Save next=null, reverse 4's link
null ← 1 ← 2 ← 3 ← 4
prev curr=null
Result: 4 → 3 → 2 → 1 → null
Partial reversal (positions 2 to 4):
Initial: 1 → 2 → 3 → 4 → 5
positions: 1 2 3 4 5
Goal: 1 → 4 → 3 → 2 → 5
Step 1: Find node before position 2
before = node 1
Step 2: Reverse nodes 2, 3, 4
1 null ← 2 ← 3 ← 4 5
↑ ↑ ↑
before prev curr
Step 3: Reconnect
before.next.next = curr (2 → 5)
before.next = prev (1 → 4)
Result: 1 → 4 → 3 → 2 → 5
Use this skeleton as a starting point for problems using this pattern:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverse_list(head: ListNode) -> ListNode:
"""Reverse entire linked list."""
prev = None
curr = head
while curr:
next_node = curr.next # Save next
curr.next = prev # Reverse link
prev = curr # Advance prev
curr = next_node # Advance curr
return prev # New head
def reverse_between(head: ListNode, m: int, n: int) -> ListNode:
"""Reverse nodes from position m to n (1-indexed)."""
if not head or m == n:
return head
dummy = ListNode(0)
dummy.next = head
before = dummy
# Move to node before reversal starts
for _ in range(m - 1):
before = before.next
# Reverse n - m + 1 nodes
prev = None
curr = before.next
for _ in range(n - m + 1):
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
# Reconnect
before.next.next = curr # tail of reversed → rest of list
before.next = prev # before → new head of reversed
return dummy.next
def reverse_k_group(head: ListNode, k: int) -> ListNode:
"""Reverse nodes in groups of k."""
# Count total nodes
count = 0
node = head
while node:
count += 1
node = node.next
dummy = ListNode(0)
dummy.next = head
before = dummy
while count >= k:
# Reverse k nodes
prev = None
curr = before.next
for _ in range(k):
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
# Reconnect
tail = before.next
tail.next = curr
before.next = prev
# Move to next group
before = tail
count -= k
return dummy.next
def reverse_list_recursive(head: ListNode) -> ListNode:
"""Reverse list using recursion."""
if not head or not head.next:
return head
new_head = reverse_list_recursive(head.next)
head.next.next = head # Reverse link
head.next = None # Prevent cycle
return new_headLook for these keywords and patterns in problem descriptions:
Reversing curr.next before saving it means you can't advance to the
next node.
Fix:
Always save the next node first:
next_node = curr.next # Save FIRST
curr.next = prev # Then reverse
Reversing the middle portion without reconnecting it to the beginning and end of the list breaks the list.
Fix:
After reversing, reconnect both ends:
before.next.next = curr # tail → rest
before.next = prev # before → new head
Reverse the entire linked list. Simplest form—just walk through and reverse each link.
Examples: Reverse Linked List
Reverse only nodes between positions m and n. Need to track connection points before and after the reversed section.
Examples: Reverse Linked List II
Reverse every k consecutive nodes. Often requires counting total nodes first to know when to stop.
Examples: Reverse Nodes in k-Group
Reverse every other group of k nodes. Combines k-group logic with skip logic.
Examples: Reverse Alternate K Nodes
Elegant recursive solution that reverses by relying on the recursive call to reverse the rest, then fixing up the current node.
Examples: Reverse Linked List (recursive approach)
Master the pattern with these representative problems.
Explore similar techniques:
Use two pointers to traverse data from different positions, often moving toward or away from each other. This technique transforms O(n²) brute force into O(n) by eliminating redundant comparisons.
Use two pointers moving at different speeds to detect cycles, find midpoints, or identify patterns in sequences. The fast pointer advances twice as quickly, allowing detection of structural properties without extra space.
When the reversal might include the head, handling the head separately adds complexity and edge cases.
Fix:
Use a dummy node pointing to head. This simplifies edge cases:
dummy = ListNode(0)
dummy.next = head
# ... reversal logic ...
return dummy.next
Confusing 0-indexed vs 1-indexed positions causes reversal of wrong nodes.
Fix:
Clarify indexing convention. For 1-indexed positions, loop m-1 times
to reach the node before position m.