MediumLinked List

Merge In Between Linked Lists โ€” Solution

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
โ†’โˆ…
[0,1,2,3,4,5]

With a = 3, b = 4, and list2:

100
โ†’
101
โ†’
102
โ†’โˆ…
[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.

  1. Walk list1 a - 1 steps from the head to reach before_gap โ€” the last node that stays in the original list before the splice point.
  2. From before_gap, walk b - a + 2 more steps to reach after_gap โ€” the first node that resumes after the removed range.
  3. Traverse list2 to find its tail node.
  4. Set before_gap.next = list2 to attach list2's head right after the anchor.
  5. Set list2_tail.next = after_gap to reconnect the rest of list1.
  6. 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 list1

Time: 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

ApproachTimeSpaceWhen to use
Pointer SurgeryO(n + m)O(1)Always; there is no alternative approach

Common Mistakes

  • Stopping at index a instead of a-1 for before_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: From before_gap (index a-1), reaching index b+1 takes exactly b - a + 2 steps. Using b - a + 1 lands 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 index b are silently dropped.
  • Trying to reuse before_gap as the starting point for after_gap vs starting fresh from the head: Starting from before_gap is correct and avoids a second O(n) traversal from the head; starting fresh from the head wastes time and is unnecessary.
  • Assuming a = 0 is impossible: It is valid. When a = 0, before_gap should be "nothing" โ€” the splice replaces from the very start. However, the problem guarantees 1 <= a, so in practice this case does not arise; knowing the constraint avoids over-engineering a dummy-head solution.

Related Problems

Ready to practice? Try it on SkillFlow

Adaptive problems, AI follow-up interviews, and a skill score that shows exactly where you need to improve.

Practice This Problem โ†’