LeetCode – Merge Sorted Array (Java)

Given two sorted integer arrays A and B, merge B into A as one sorted array.

Note:
You may assume that A has enough space to hold additional elements from B. The number of elements initialized in A and B are m and n respectively.

Analysis

The key to solve this problem is moving element of A and B backwards. If B has some elements left after A is done, also need to handle that case.

The takeaway message from this problem is that the loop condition. This kind of condition is also used for merging two sorted linked list.

Java Solution 1

public class Solution {
    public void merge(int A[], int m, int B[], int n) {
 
        while(m > 0 && n > 0){
            if(A[m-1] > B[n-1]){
                A[m+n-1] = A[m-1];
                m--;
            }else{
                A[m+n-1] = B[n-1];
                n--;
            }
        }
 
        while(n > 0){
            A[m+n-1] = B[n-1];
            n--;
        }
    }
}

Java Solution 2

The loop condition also can use m+n like the following.

public void merge(int A[], int m, int B[], int n) {
	int i = m - 1;
	int j = n - 1;
	int k = m + n - 1;
 
	while (k >= 0) {
		if (j < 0 || (i >= 0 && A[i] > B[j]))
			A[k--] = A[i--];
		else
			A[k--] = B[j--];
	}
}
Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • fishwen

    solution is in place merge, good coding!

  • Mike Chen

    We must need to have a function to initialize array A & B, and then pass these to merge function. But it shows ArrayIndexOutOfBoundsException error. What should I do to correct this?

  • Holden

    why in the second solution, both “A finished: i<0" and "B finished: j<0" are considered, but in the first one, we only need to take care of remaining elements from array B?
    I mean why in the second solution, we should consider both cases?

  • Holden

    You should put the code inside and tags or post your code in: http://ideone.com, then put its link here 🙂

  • Holden

    why in the while loop, we only need to check (n >= 0)?

  • Holden

    why do we need to put m–; and n–;before the while loop?

  • Holden

    You should post you code in Ideone, then put the link here

  • Holden

    why in the second solution, both “A finished: i<0" and "B finished: j<0" are considered, but in the first one, we only need to take care of remaining elements from array B?
    I mean why in the second solution, we should consider both cases?

  • Vishal

    //This should work
    public void merge(int A[], int m, int B[], int n) {

    int lind=0;

    int rind=0;

    int dind=0;

    int[] dest=new int[m+n];

    while(lind<m && rind<n)

    {

    if(A[lind] < B[rind])

    dest[dind++]=A[lind++];

    else

    dest[dind++]=B[rind++];

    }

    while(lind < m)

    dest[dind++]=A[lind++];

    while(rind < n)

    dest[dind++]=B[rind++];

    System.arraycopy(dest,0,A,0,A.length);

    }

  • Vishal

    //There was some issue while pasting it.. I hope this looks ok

    public void merge(int A[], int m, int B[], int n) {

    int lind=0;

    int rind=0;

    int dind=0;

    int[] dest = new int[m+n];

    while(lind<m && rind<n)

    {

    if(A[lind] < B[rind])

    dest[dind++]=A[lind++];

    else

    dest[dind++]=B[rind++];

    }

    while(lind < m)

    dest[dind++]=A[lind++];

    while(rind < n)

    dest[dind++]=B[rind++];

    System.arraycopy(dest,0,A,0,A.length);

    }

  • Vishal

    public void merge(int A[], int m, int B[], int n) {

    int lind=0;
    int rind=0;
    int dind=0;

    int[] dest = new int[m+n];

    while(lind<m && rind<n)
    {
    if(A[lind] < B[rind]) dest[dind++]=A[lind++];
    else dest[dind++]=B[rind++];
    }

    while(lind < m) dest[dind++]=A[lind++];

    while(rind < n) dest[dind++]=B[rind++];

    System.arraycopy(dest,0,A,0,A.length);
    }

  • Howard

    For solution 1:

    while(n>0){
    A[n-1]=B[n-1]; // since in this condition, m equals to 0
    n–;
    }

  • bond0007

    void merge(int A[], int m, int B[], int n) {

    int k=m+n-1;

    m–;

    n–;

    while(n>=0)

    {

    if(m >=0 && A[m] > B[n])

    A[k–] = A[m–];

    else

    A[k–] = B[n–];

    }

    }

  • Farah El Uasghiri

    The two solutions dont working …

  • Arzimao

    // Sorry for the previous messy code, re post

    public class MergeSortedArray {

    public static int[] merge(int[] arrA, int[] arrB){

    int[] mrgArr = new int[]{};

    if (arrA.length==0 && arrB.length==0) return mrgArr;

    if (arrA.length==0) return arrB;

    if (arrB.length==0) return arrA;

    int aPointer = 0;

    int bPointer = 0;

    while(aPointer<arrA.length || bPointer<arrB.length){

    if(aPointer == arrA.length-1 && bPointer < arrB.length-1){

    mrgArr = append(mrgArr, arrB[bPointer]);

    bPointer++;

    }

    if(aPointer < arrA.length-1 && bPointer == arrB.length-1){

    mrgArr = append(mrgArr, arrA[aPointer]);

    aPointer++;

    }

    if (arrA[aPointer] < arrB[bPointer]){

    mrgArr = append(mrgArr, arrA[aPointer]);

    aPointer++;

    }else if(arrA[aPointer] == arrB[bPointer]){

    mrgArr = append(mrgArr, arrA[aPointer]);

    aPointer++;

    bPointer++;

    }else{

    mrgArr = append(mrgArr, arrB[bPointer]);

    bPointer++;

    }

    }

    return mrgArr;

    }

    private static int[] append(int[] arrInt, int val){

    arrInt = Arrays.copyOf(arrInt, arrInt.length+1);

    arrInt[arrInt.length-1] = val;

    return arrInt;

    }

    public static void main(String[] args){

    int[] arrA = new int[]{1, 3, 4, 6, 8, 9, 13, 27, 18};

    int[] arrB = new int[]{2, 5, 8, 7, 10, 18, 16, 21, 27, 25};

    Arrays.sort(arrA);

    Arrays.sort(arrB);

    System.out.println(Arrays.toString(merge(arrA, arrB)));

    }

    }

  • Arzimao

    A solution no need any assumption and take care all situation.

    public class MergeSortedArray {

    public static int[] merge(int[] arrA, int[] arrB){

    int[] mrgArr = new int[]{};

    if (arrA.length==0 && arrB.length==0) return mrgArr;

    if (arrA.length==0) return arrB;

    if (arrB.length==0) return arrA;

    int aPointer = 0;

    int bPointer = 0;

    while(aPointer<arrA.length || bPointer<arrB.length){

    if(aPointer == arrA.length-1 && bPointer < arrB.length-1){

    mrgArr = append(mrgArr, arrB[bPointer]);

    bPointer++;

    }

    if(aPointer < arrA.length-1 && bPointer == arrB.length-1){

    mrgArr = append(mrgArr, arrA[aPointer]);

    aPointer++;

    }

    if (arrA[aPointer] < arrB[bPointer]){

    mrgArr = append(mrgArr, arrA[aPointer]);

    aPointer++;

    }else if(arrA[aPointer] == arrB[bPointer]){

    mrgArr = append(mrgArr, arrA[aPointer]);

    aPointer++;

    bPointer++;

    }else{

    mrgArr = append(mrgArr, arrB[bPointer]);

    bPointer++;

    }

    }

    return mrgArr;

    }

    private static int[] append(int[] arrInt, int val){

    arrInt = Arrays.copyOf(arrInt, arrInt.length+1);

    arrInt[arrInt.length-1] = val;

    return arrInt;

    }

    public static void main(String[] args){

    int[] arrA = new int[]{1, 3, 4, 6, 8, 9, 13, 27, 18};

    int[] arrB = new int[]{2, 5, 8, 7, 10, 18, 16, 21, 27, 25};

    Arrays.sort(arrA);

    Arrays.sort(arrB);

    System.out.println(Arrays.toString(merge(arrA, arrB)));

    }

    }

  • outlook

    not a bug. For the case you mentioned, the remaining elements in A are already there as they were expected to be. Don’t need to restore them in the same position.

  • Milton

    There is a bug in Solution1, when the first loop ended with m > 0 and n == 0;