[Medium] 92. Reverse Linked List II
Given the head of a singly linked list and two integers left and right where left <= right, reverse the nodes of the list from position left to position right (1-indexed), and return the reversed list.
Examples
Example 1:
Input: head = [1,2,3,4,5], left = 2, right = 4
Output: [1,4,3,2,5]
1 → [2 → 3 → 4] → 5
↓ reverse ↓
1 → [4 → 3 → 2] → 5
Example 2:
Input: head = [5], left = 1, right = 1
Output: [5]
Constraints
1 <= n <= 500(number of nodes)-500 <= Node.val <= 5001 <= left <= right <= n
Thinking Process
Break It Into 3 Parts
- Traverse to the node before
left– call itprev - Reverse the sublist
[left .. right] - Reconnect:
prev → new head of reversed sublist,tail of reversed sublist → node after right
The Head Insertion Trick
Instead of doing a standard three-pointer reversal and then reconnecting, we can use head insertion: repeatedly pull the node after curr to the front of the sublist. This avoids re-traversing and naturally keeps all connections intact.
Initial: prev → [a → b → c → d] → next
↑ ↑
left right
Step 1: move b before a
prev → [b → a → c → d] → next
Step 2: move c before b
prev → [c → b → a → d] → next
Step 3: move d before c
prev → [d → c → b → a] → next
Each step does 3 pointer swaps and the sublist grows by one node at the front.
Edge Cases
| Case | Handling |
|---|---|
left == 1 (head changes) |
Dummy node absorbs head change |
left == right (no-op) |
Early return |
| Single node | Early return |
Common Approaches
Typical techniques for this pattern:
| Approach | Time | Space | Notes |
|---|---|---|---|
| Iterative pointer walk (this problem) | O(n) | O(1) | Traversal, insertion |
| Dummy head node | O(n) | O(1) | Simplify head-edge cases |
| Reversal (3-pointer) | O(n) | O(1) | Reverse sublist or full list |
| Slow/fast pointers | O(n) | O(1) | Middle, cycle, merge lists |
Solution
from typing import Optional
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseBetween(
self, head: Optional["ListNode"], left: int, right: int
) -> Optional["ListNode"]:
if not head or left == right:
return head
dummy = ListNode(0, head)
prev = dummy
# Move prev to node before 'left'.
for _ in range(left - 1):
prev = prev.next
# Reverse sublist using head insertion.
curr = prev.next
for _ in range(right - left):
nxt = curr.next
curr.next = nxt.next
nxt.next = prev.next
prev.next = nxt
return dummy.next
Solution Explanation
Approach: Iterative pointer walk (this problem)
Key idea: ### Break It Into 3 Parts
How the code works:
- Traverse to the node before
left– call itprev - Reverse the sublist
[left .. right] - Reconnect:
prev → new head of reversed sublist,tail of reversed sublist → node after right
Walkthrough — input head = [1,2,3,4,5], left = 2, right = 4, expected output [1,4,3,2,5]:
- Initialize variables from the problem setup.
- Apply the main loop / recursion until the condition is met.
- Confirm the result matches the expected output.
Comparison
| Aspect | Head Insertion | Classic Reversal |
|---|---|---|
| Uses dummy node | Yes (handles left == 1) |
No (explicit if for left == 1) |
curr pointer movement |
Stays fixed | Advances through sublist |
| Reconnection | Automatic (pointers stay connected) | Manual (set con.next and tail.next) |
| Conceptual complexity | Lower – single pattern repeated | Higher – two distinct phases |
Common Mistakes
- Off-by-one on
prev: Walkingleftsteps from dummy lands on nodeleft, but we need nodeleft - 1. Walkleft - 1steps instead. - Moving
currin head insertion:currshould stay fixed – it’s always the tail of the growing reversed sublist. Onlytmpmoves. - Forgetting
left == 1: Without a dummy, the head of the list changes. Either use a dummy or handle this case explicitly.
Key Takeaways
- Head insertion is the cleanest pattern for partial reversal – no separate reconnection step needed
- A dummy node eliminates the
left == 1edge case entirely - Both approaches are O(n) time and O(1) space – the choice is about clarity, not performance
Related Problems
- 206. Reverse Linked List – full list reversal
- 25. Reverse Nodes in k-Group – reverse segments of size k
- 24. Swap Nodes in Pairs – special case of k=2 reversal
- 1669. Merge In Between Linked Lists – similar pointer surgery on a sublist range
References
- LC 92: Reverse Linked List II on LeetCode
- LeetCode Discuss — LC 92: Reverse Linked List II
- LeetCode Editorial (may require premium)