链接:88. 合并两个有序数组
题目描述
真题描述:给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
说明: 初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
解析
标准解法:双指针法
定义两个指针,各指向两个数组生效部分的尾部。
每次只对指针所指的元素进行比较。取其中较大的元素,把它从 nums1 的末尾往前面填补。
从后往前填补的原因是,要把所有的值合并到 nums1 里,但是nums1不是空的,而是前面几个坑有内容的。如果我们从前往后填补,就没法直接往对应的坑位赋值了(会产生值覆盖)。
从后往前填补,我们填的都是没有内容的坑,可以直接把值放进去,这样会省掉很多麻烦。
由于 nums1 的有效部分和 nums2 并不一定是一样长的。我们还需要考虑其中一个提前到头的这种情况:
- 如果提前遍历完的是 nums1 的有效部分,剩下的是 nums2。那么这时意味着 nums1 的头部空出来了,直接把 nums2 整个补到 nums1 前面去即可。
- 如果提前遍历完的是 nums2,剩下的是 nums1。由于容器本身就是 nums1,所以此时不必做任何额外的操作。
代码实现
var merge = function(nums1, m, nums2, n) {
let i = m - 1;
let j = n - 1;
let k = m + n - 1;
while(i >= 0 && j >= 0){
if(nums1[i] > nums2[j]){
nums1[k] = nums1[i];
i--;
k--;
} else {
nums1[k] = nums2[j];
j--;
k--;
}
}
// nums1中的数字已经比较完
// nums2中还有未插入的数字
// 将nums2中剩下的数按顺序放进nums1即可
while(j >= 0){
nums1[k] = nums2[j];
j--;
k--;
}
};