This is the merge step from merge sort, with one constraint: we have to merge in-place into nums1, which already has extra space at the end to hold all elements from nums2.
Merging from the front, comparing the smallest elements first, runs into a problem. If nums2[0] is smaller than nums1[0], placing it at the front of nums1 overwrites a value we have not processed yet. Avoiding that means shifting elements right, which turns a linear operation into O(m \* n).
The back of nums1 is empty, filled with placeholder zeroes. Merging from the back instead, placing the largest elements first, writes into those empty slots and never overwrites a value we still need.
1 <= m + n <= 200 → The input is small enough that any correct approach passes, but the follow-up asks for O(m + n), which is the target.nums1.length == m + n → The extra space at the end of nums1 holds all elements from nums2 exactly, so an in-place solution is possible.-10^9 <= nums1[i], nums2[j] <= 10^9 → Values fit in a 32-bit signed integer, and negative numbers are possible, so comparisons must not assume positive values.Copy all elements from nums2 into the empty slots at the back of nums1, then sort the entire array. A built-in sort produces the final order without any merge logic.
This ignores the fact that both arrays are already sorted and treats the problem as a generic "combine and sort" task. That wasted information is why it is slower than necessary, but it is correct and short, which makes it a useful baseline.
nums2 into nums1 starting at index m.nums1 array.The next approach uses the fact that both arrays are already sorted to merge them in a single linear pass, avoiding the re-sort entirely.
Both arrays are sorted, so their largest elements sit at the ends, and the placeholder slots at the back of nums1 are exactly where the largest merged values belong. Start from the back of both arrays, compare the two largest unplaced elements, place the bigger one at the end of nums1, and move the pointers backward.
The write always lands in a slot that is either a placeholder or a nums1 element that has already been read. The next section justifies why that conflict-free property holds at every step.
The write pointer k never passes the read pointer i. They start at k = m + n - 1 and i = m - 1, so the gap k - i = n. Each iteration decreases k by 1, and decreases i by at most 1 (only when the element comes from nums1). The gap therefore never shrinks, staying at least n >= 0. So k is always at or ahead of i, and writing to nums1[k] never clobbers a nums1 value that has not been read yet.
When nums2 is exhausted first, the remaining nums1 elements already occupy their correct positions at the front of the array and are never moved. Only leftover nums2 elements still need to be copied, which the cleanup loop handles.
i = m - 1 (end of valid elements in nums1), j = n - 1 (end of nums2), and k = m + n - 1 (end of nums1).i >= 0 and j >= 0:nums1[i] > nums2[j], place nums1[i] at position k and decrement i.nums2[j] at position k and decrement j.k.nums2 (j >= 0), copy them into nums1.nums1 since they're already in place.