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--]; } } |
Since we merge b into a, I would change a little bit the loop like this:
private void merge(int[] a, int n, int[] b, int m) {
int i = n - 1;
int j = m - 1;
int k = n + m - 1;
while (j >= 0) {
if (i>=0 && a[i] > b[j])
a[k--] = a[i--];
else
a[k--] = b[j--];
}
}
Check out this one:
public void merge(int[] nums1, int m, int[] nums2, int n) {
for (int i = 0;i < n;i++){
nums1[i + m] = nums2[i];
}
Arrays.sort(nums1);
}
}
public void merge(int[] array1, int len1, int[] array2, int len2) {
int arrayIndex1 = len1 - 1; // position of last element
int arrayIndex2 = len2 - 1;
int mergedIndex = len1 + len2 - 1;
while (arrayIndex1 >= 0 || arrayIndex2 >= 0) {
if (arrayIndex2 >= 0 && (arrayIndex1 array1[arrayIndex1] )) {
array1[mergedIndex] = array2[arrayIndex2];
arrayIndex2--;
} else {
array1[mergedIndex] = array1[arrayIndex1];
arrayIndex1--;
}
mergedIndex--;
}
}
solution is in place merge, good coding!
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?
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?
You should put the code inside and tags or post your code in: http://ideone.com, then put its link here 🙂
why in the while loop, we only need to check (n >= 0)?
why do we need to put m–; and n–;before the while loop?
You should post you code in Ideone, then put the link here
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?
//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);
}
//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);
}
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);
}
For solution 1:
while(n>0){
A[n-1]=B[n-1]; // since in this condition, m equals to 0
n–;
}
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–];
}
}
The two solutions dont working …
// 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)));
}
}
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)));
}
}
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.
There is a bug in Solution1, when the first loop ended with m > 0 and n == 0;