持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【LeetCode 88. 合并两个有序数组 】- JavaScript(双指针)
题目描述
给你两个按 非递减顺序 排列的整数数组 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] ,其中斜体加粗标注的为 nums1 中的元素。
双指针
思路分析:
整体的的思路:主要这里要改变的是nums1,作为函数的参数,js属于值传递,所以在函数里面的数组的方法得改变数组本身,也就是说不能构造出一个新的数组,最后让nums1指向它,这样其实最后nums1指向的原数组并没有改变,而我们恰恰要改变的是原数组。所以应该使用一些可以改变数组本身的方法,如Array.push、Array.splice这些。具体实现步骤如下:
- 从后往前遍历,比较nums1[i]和nums2[j]大小
- nums2[j]大,注意nums1为空的情况,即i==-1,此时将nums2依次装入nums1即可
- nums1[i]大,反之
- 当j == -1的时候跳出,完成排序
- 由于数组1的数组空间大于等于 m+n,所以第一步可以先计算最大值在数组1中的位置last,last=m+n-1
- 接下来可以在nums1和nums2中,依次计算出最大值按照last放入num1,每次取值的时候后将last和 m或n减一。
- 最终可能会有两种情况:(1)m先为0,跳出while,这种情况需要将num2剩余未放进num1的数值放入num1
- 如果n先为0,这种情况不需要做处理,num1已经是要求的结果。
var merge = function(nums1, m, nums2, n) {
let i = 0, j = 0, k = 0;
let res = new Array(m+n).fill(0);
while(i <m && j < n) {
if(nums1[i] < nums2[j]) {
res[k] = nums1[i];
i++;
} else {
res[k] = nums2[j];
j++;
}
k++;
}
for (; i < m; i++) {
res[k] = nums1[i];
k++;
}
for (; j < n; j++) {
res[k] = nums2[j];
k++;
}
res.forEach((element, index) => nums1[index] = element);
return nums1;
};
思考
其实我们可以将此题看成归并排序的变形,即将nums1[0....m-1]与nums2[m.....m+n-1]进行归并,首先将这两个数组复制到一个数组中,然后利用三指针,不断地进行比较。算是一个比较简单的题目了。
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤