Problem
You have two linked lists: list1 and list2, plus two indices a and b. Remove every node in list1 from index a to index b (inclusive), then splice list2 in where those nodes used to be. The rest of list1 stays intact before and after the inserted section.
[0,1,2,3,4,5]
With a = 3, b = 4, and list2:
[100,101,102]
- Input: list1 = [0, 1, 2, 3, 4, 5], a = 3, b = 4, list2 = [100, 101, 102]
- Output: [0, 1, 2, 100, 101, 102, 5]
- Explanation: Nodes at index 3 (value 3) and index 4 (value 4) are removed and replaced by all of list2.
Intuition
To splice list2 in, you don't need the removed nodes โ you only need their immediate neighbors: the node just before the gap and the node just after it. Walk list1 to find those two anchor points, walk list2 to find its tail, then reconnect three pointers. The removed nodes are simply abandoned.
Solution โ Pointer Surgery
Find the left anchor (node at index a-1), find the right anchor (node at index b+1) by continuing from the left anchor, find list2's tail, then rewire.
- Walk list1
a - 1steps from the head to reachbefore_gapโ the last node that stays in the original list before the splice point. - From
before_gap, walkb - a + 2more steps to reachafter_gapโ the first node that resumes after the removed range. - Traverse list2 to find its tail node.
- Set
before_gap.next = list2to attach list2's head right after the anchor. - Set
list2_tail.next = after_gapto reconnect the rest of list1. - Return the original list1 head โ it is unchanged.
1def mergeInBetween(list1: ListNode, a: int, b: int, list2: ListNode) -> ListNode:
2 # stop at index a-1: the last node before the removed range
3 before_gap = list1
4 for _ in range(a - 1):
5 before_gap = before_gap.next
6
7 # from before_gap, advance b-a+2 steps to clear all removed nodes
8 after_gap = before_gap
9 for _ in range(b - a + 2):
10 after_gap = after_gap.next
11
12 list2_tail = list2
13 while list2_tail.next:
14 list2_tail = list2_tail.next
15
16 before_gap.next = list2
17 list2_tail.next = after_gap
18 return list1Time: O(n + m) โ one pass over list1 to find the anchors, one pass over list2 to find its tail.
Space: O(1) โ only pointer variables, no extra storage.
Complexity Summary
| Approach | Time | Space | When to use |
|---|---|---|---|
| Pointer Surgery | O(n + m) | O(1) | Always; there is no alternative approach |
Common Mistakes
- Stopping at index
ainstead ofa-1forbefore_gap: You need the predecessor of the first removed node โ the one that will point into list2. Stopping one step too late means list2 replaces one fewer node than intended. - Wrong step count for
after_gap: Frombefore_gap(indexa-1), reaching indexb+1takes exactlyb - a + 2steps. Usingb - a + 1lands you on the last removed node, so the tail of list2 points back into the removed range rather than past it. - Forgetting to traverse list2's tail: Without finding the tail, you have no way to reconnect
after_gapโ the nodes in list1 after indexbare silently dropped. - Trying to reuse
before_gapas the starting point forafter_gapvs starting fresh from the head: Starting frombefore_gapis correct and avoids a second O(n) traversal from the head; starting fresh from the head wastes time and is unnecessary. - Assuming
a = 0is impossible: It is valid. Whena = 0,before_gapshould be "nothing" โ the splice replaces from the very start. However, the problem guarantees1 <= a, so in practice this case does not arise; knowing the constraint avoids over-engineering a dummy-head solution.
Related Problems
Reverse Linked List IIโ modifies a subrange of a linked list by reversing it, using the same left/right anchor techniqueRemove Nth Node From End of Listโ precise pointer navigation to remove a node by rewiring its predecessorMerge Two Sorted Listsโ pointer-by-pointer linked list construction; same style ofnextreassignmentReorder Listโ restructures a linked list with multiple pointer manipulation passesReverse Nodes in K-Groupโ group-by-group splicing of linked list segments using anchor pointers