给你两个按 非递减顺序 排列的整数数组 nums1 **和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 **到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意: 最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
示例 1:
输入: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
解释: 需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6]
思考
看完题呢,脑子里第一个想法就是暴力 ,将他们合并 然后nums.sort((a,b)=>a-b)(a-b为升序)就解决了。但是很明显 不是题目所要考察的
T u T 啊,孩子真的没救了吗?
既然不用sort,那我们想想其他的办法吧
首先呢 可以建立两个索引 index1,index2分别指向num1和num2的第一个数
既然要把num2加入num1,那么就从num2[index2]开始比较num1[index1],如果遇见比num2[index2]大的数,那么就可以将num2[index2]插入num1[index1]前面,同时呢,num1往后面挤掉一个0。同时呢,如果num1最后一个非0数都比num2第一个数小,那么直接将num2全部加入到num1.
function merge(nums1, m, nums2, n) {
// 从 nums2 中逐一取出元素
for (let i = 0; i < n; i++) {
// 当前需要插入的元素
let current = nums2[i];
// 在 nums1 的前 m+i 个元素中找到插入位置
let j = 0;
while (j < m + i && nums1[j] <= current) {
j++;
}
// 插入元素并更新 nums1 的长度
nums1.splice(j, 0, current);
nums1.pop(); // 移除最后一个 0 以保持数组长度
}
}
let nums1 = [1, 2, 3, 0, 0, 0];
let m = 3;
let nums2 = [2, 5, 6];
let n = 3;
merge(nums1, m, nums2, n);
console.log(nums1); // 输出应为 [1, 2, 2, 3, 5, 6]
用了数组的内置方法还这么费劲,再想想吧…… 那么前面这么费劲,后面呢,我们不妨从后面来。 两个索引都指向数组的末尾有效值,我们比较他们的大小,谁大,就去num1的最后,如此循环 好像也可以?!!
var merge = function(nums1, m, nums2, n){
let p1 = m - 1, p2 = n - 1, p = m + n - 1;
while (p2 >= 0) { // nums2 还有要合并的元素
// 如果 p1 < 0,那么走 else 分支,把 nums2 合并到 nums1 中
if (p1 >= 0 && nums1[p1] > nums2[p2]) {
nums1[p--] = nums1[p1--];
// 填入
nums1[p1]
} else {
nums1[p--] = nums2[p2--];
// 填入
nums2[p1]
}
}
}
事实证明也是可以的。