You are given two sorted arrays, A and B, where A has a large enough buffer at the end to hold B. Write a method to merge B into A in sorted order.
Initially the number of elements in A and B are m and n respectively.
Example:
Input:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
Solutions
Solution 1: Two Pointers
Thinking
\(B\) must merge into the spare tail of \(A\). Writing from the front overwrites unread values of \(A\). A third buffer uses linear extra space.
The unused suffix of \(A\) can hold the whole result, so placing the larger tail element first leaves the unread prefixes intact.
Pointers \(i\) and \(j\) sit at the live ends; \(k\) walks \(m+n-1\) downward. Write \(A[i]\) when \(B\) is exhausted or \(A[i]\) is larger, otherwise \(B[j]\).
We use two pointers \(i\) and \(j\) to point to the end of arrays \(A\) and \(B\) respectively, and a pointer \(k\) to point to the end of array \(A\). Then we traverse arrays \(A\) and \(B\) from back to front, each time putting the larger element into \(A[k]\), then moving pointer \(k\) and the pointer of the array with the larger element forward by one position.
The time complexity is \(O(m + n)\), and the space complexity is \(O(1)\).
/** Do not return anything, modify A in-place instead. */functionmerge(A:number[],m:number,B:number[],n:number):void{let[i,j]=[m-1,n-1];for(letk=A.length-1;~k;--k){if(j<0||(i>=0&&A[i]>B[j])){A[k]=A[i--];}else{A[k]=B[j--];}}}
/** * @param {number[]} A * @param {number} m * @param {number[]} B * @param {number} n * @return {void} Do not return anything, modify A in-place instead. */varmerge=function(A,m,B,n){let[i,j]=[m-1,n-1];for(letk=A.length-1;~k;--k){if(j<0||(i>=0&&A[i]>B[j])){A[k]=A[i--];}else{A[k]=B[j--];}}};