Merge Sorted Array — O(m+n) In-Place from End [Meta Top Question]

Sanjeev SharmaSanjeev Sharma
3 min read

Advertisement

Problem Statement

You are given two integer arrays nums1 and nums2, sorted in non-decreasing order, and two integers m and n, representing the number of elements in nums1 and nums2 respectively. Merge nums2 into nums1 in-place. nums1 has extra space at the end to hold nums2.

Example:

Input:  nums1 = [1,2,3,0,0,0], m=3   nums2 = [2,5,6], n=3
Output: [1,2,2,3,5,6]

Intuition

Fill from the end: Instead of inserting and shifting (O(m·n)), place the largest elements at the back of nums1 first. Use three pointers: p1 = m-1, p2 = n-1, write = m+n-1.

p1 = m-1,  p2 = n-1,  write = m+n-1

while p1 >= 0 and p2 >= 0:
    if nums1[p1] > nums2[p2]:
        nums1[write] = nums1[p1]; p1--
    else:
        nums1[write] = nums2[p2]; p2--
    write--

# Copy remaining nums2 (if any)
while p2 >= 0:
    nums1[write--] = nums2[p2--]

Why does this work? We always place the globally largest remaining element, and we never overwrite an element of nums1 that hasn't been considered yet.

Solutions in All 5 Languages

C

void merge(int* nums1, int m, int* nums2, int n) {
    int p1 = m - 1, p2 = n - 1, write = m + n - 1;
    while (p1 >= 0 && p2 >= 0) {
        if (nums1[p1] > nums2[p2])
            nums1[write--] = nums1[p1--];
        else
            nums1[write--] = nums2[p2--];
    }
    while (p2 >= 0) nums1[write--] = nums2[p2--];
}

C++

#include <vector>
using namespace std;

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int p1 = m-1, p2 = n-1, write = m+n-1;
        while (p1 >= 0 && p2 >= 0) {
            nums1[write--] = (nums1[p1] > nums2[p2]) ? nums1[p1--] : nums2[p2--];
        }
        while (p2 >= 0) nums1[write--] = nums2[p2--];
    }
};

Java

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1 = m-1, p2 = n-1, write = m+n-1;
        while (p1 >= 0 && p2 >= 0) {
            nums1[write--] = (nums1[p1] > nums2[p2]) ? nums1[p1--] : nums2[p2--];
        }
        while (p2 >= 0) nums1[write--] = nums2[p2--];
    }
}

JavaScript

function merge(nums1, m, nums2, n) {
    let p1 = m-1, p2 = n-1, write = m+n-1;
    while (p1 >= 0 && p2 >= 0) {
        nums1[write--] = nums1[p1] > nums2[p2] ? nums1[p1--] : nums2[p2--];
    }
    while (p2 >= 0) nums1[write--] = nums2[p2--];
}

Python

from typing import List

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        p1, p2, write = m-1, n-1, m+n-1
        while p1 >= 0 and p2 >= 0:
            if nums1[p1] > nums2[p2]:
                nums1[write] = nums1[p1]; p1 -= 1
            else:
                nums1[write] = nums2[p2]; p2 -= 1
            write -= 1
        while p2 >= 0:
            nums1[write] = nums2[p2]; p2 -= 1; write -= 1

Complexity: O(m+n) time, O(1) space

Next: Problem 8 — Remove Duplicates from Sorted Array

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro