Merge Sorted Array
Merge Sorted Array
You are given two non-decreasing integer arrays. The first array nums1 has a length of m + n, where the first m elements are valid and the last n elements are empty placeholders. The second array nums2 has length n and is fully valid.
Your task is to merge nums2 into nums1 so that nums1 becomes fully sorted. The merge must be in-place.
A naive merge from the front overwrites data you still need. The key is to work from the end.
Why this is worth learning
The spare slots are at the right, so make the right-hand suffix final first. This is an overwrite-order problem, not a reason to allocate another merged array.
Before coding: one-minute experiment
With nums1=[2,4,0,0], m=2, nums2=[1,3], n=2, what are the four values written from right to left?
Function signature
func MergeSortedArray(nums1 []int, m int, nums2 []int, n int)
Inputs / outputs
nums1: lengthm + n, sorted in its firstmpositions.m: number of valid elements innums1.nums2: lengthn, sorted in all positions.n: number of elements innums2.- Return: nothing.
nums1must be modified in-place to contain the merged result.
Example
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
After merge: nums1 = [1,2,2,3,5,6]
Constraints
0 <= m, n <= 100_000len(nums1) == m + nnums1[0:m]is sortednums2is sorted
Core idea (near-solution)
Use three pointers from the end:
i = m - 1points at the last valid element ofnums1.j = n - 1points at the last element ofnums2.write = m + n - 1points at the last slot innums1.
Invariant: everything after write is already in its final, sorted position.
At each step, place the larger of nums1[i] and nums2[j] at nums1[write], then decrement the pointer you used. This works because the largest remaining element must belong at the end.
Algorithm (step-by-step)
- Initialize
i = m-1,j = n-1,write = m+n-1. - While
j >= 0(there is still data to place fromnums2):- If
i >= 0andnums1[i] > nums2[j], writenums1[i]tonums1[write], theni--. - Otherwise, write
nums2[j]tonums1[write], thenj--. - Always decrement
writeafter a write.
- If
- When
j < 0, the merge is complete.
Correctness sketch
Let i and j be the last unread indices and w=i+j+1 the next destination. Initially the final suffix is empty. Among the unread values, sortedness makes max(nums1[i], nums2[j]) the largest; placing it at w extends the correct suffix by one. While j>=0, w>i, so writing cannot destroy an unread value of nums1. If i<0, only nums2 remains. Every iteration consumes one value. When j<0, w=i and the remaining nums1 prefix is already in its final positions. This is the stopping argument; the three pointers do not need to meet.
Trace (hand walkthrough)
Example input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
After merge: nums1 = [1,2,2,3,5,6]
Walk:
- i=2 (3), j=2 (6), write=5 -> place 6: nums1=[1,2,3,0,0,6], j=1, write=4
- i=2 (3), j=1 (5), write=4 -> place 5: nums1=[1,2,3,0,5,6], j=0, write=3
- i=2 (3), j=0 (2), write=3 -> place 3: nums1=[1,2,3,3,5,6], i=1, write=2
- i=1 (2), j=0 (2), write=2 -> place 2 from nums2: nums1=[1,2,2,3,5,6], j=-1 stop
Pitfalls to avoid
- Merging from the front (overwrites
nums1data). - Forgetting that
nums1must have length m+n, not merely spare capacity. The final n indexed slots are writable storage. - Stopping when
i < 0(you still must copy remainingnums2elements).
Debugging lens
Use [2,0] and [1] to expose a front-writing overwrite. Also merge an empty first prefix: checking i>=0 must precede reading nums1[i]. The destination has length m+n, not merely unused capacity.
Complexity
- Time:
O(m + n) - Extra space:
O(1)
Implementation notes (Go)
- Modifying
nums1[i]updates the caller's slice (the underlying array is shared). - Always check
i >= 0before readingnums1[i].
Reconstruction checkpoint
With nums1=[2,4,0,0], m=2, nums2=[1,3], n=2, what are the four values written from right to left?
Model answer
4, 3, 2, 1. After writing 4, the unread first-array prefix is [2]; the spare suffix protects it until needed.