题目描述
给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。
初始化 A 和 B 的元素数量分别为 m 和 n。
示例:
输入:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
说明:
A.length == n + m
解题思路
因为输入数组 A,B都是有序的数组,所以我们在合并的过程中只要保证将数组 B 中的元素插入合适的位置,就能保证合并后的数组依然是有序的。
这里我们定义两个指针 pa,pb,分别指向数组 A,B 的最后一个元素。
每次让 pa 向前找到第一个小于等于 pb 指向元素的位置(如果初始 a 指向元素小于等于 b 指向元素,则无需移动),然后将 pa 指针后面的元素统一向后移动一位,在空出的位置插入 pb 指向元素。这样就保证了每次插入 B 数组中的元素都在合适的位置,插入后,数组 A 依然有序。
向前移动 pb 指针,重复上述过程,直到处理完数组 B 中的所有元素,就完成了将 B 合并入 A 的过程。
动画演示
动画:转发奔跑的蜗牛
代码实现
// 倒序排序,并从小到大排序
var merge = function(A, m, B, n) {
let pa = m - 1, pb = n - 1;
let tail = m + n - 1; //结果数组长度
let cur; //合并之后数组
while(pa >= 0 || pb >= 0){ //如果pa或者pb大于0都是可以进行合并的
// 如果大于-1证明pa合并完了
if(pa === -1){
// 合并B数组
cur = B[pb--];
}else if(pb === -1){
// 合并A数组
cur = A[pa--];
}else if(A[pa] > B[pb]){ //如果A数组大于B数组
// 把A数组放入到合并后数组
cur = A[pa--];
}else{
cur = B[pb--];
}
// 结束条件
A[tail--] = cur;
}
};