这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战
题目描述
现在有2个整数数组nums1,nums2,都是按照递增的顺序排列的,现在需要把nums2合并到nums1中,并且是按照递增的顺序返回。
另外还有2个整数(m,n),nums1的长度是m+n,m代表的是nums1需要合并的数,其它n位都是0。 n也是nums2的长度。
注意:需要直接在nums1上面修改再返回。
举个例子:
nums1:[1,2,3,0] m:3
nums2: [4] n:1
合并后的nums1: [1,2,3,4]
nums1:[0] m:0
nums2: [3] n:1
合并后的nums1: [3]
nums1:[3] m:1
nums2: [] n:0
合并后的nums1: [3]
思路分析
第一种方法
既然nums1后面的n位都是0,那么就可以把nums2的元素都迁移到那里,这样nums1就包含了所有需要排序的元素
然后对nums1进行sort升序排序即可。
代码如下:
/**
* @param {number[]} nums1
* @param {number} m
* @param {number[]} nums2
* @param {number} n
* @return {void} Do not return anything, modify nums1 in-place instead.
*/
var merge = function (nums1, m, nums2, n) {
for (let i = m; i < m + n; i++) {
nums1[i] = nums2[m + n - i - 1]
}
return nums1.sort((a, b) => a - b)
};
第二种方法
因为两个数组的都是升序排序的。
我们可以建一个m+n长度的新数组,
然后把通过对nums1和nums2进行遍历,nums1的索引是i, nums2的索引是j, 元素相互比较,较小的元素存到新数组中,较小的元素的索引加一,继续和之前大的元素比较。
如果索引i加到了m的时候,就证明已经nums1已经全部遍历,后面都使用nums2的元素就行。
如果索引j加到了n的时候,就证明已经nums2已经全部遍历,后面都使用nums1的元素就行。
直到i和j都分别等于m和n的时候,就退出循环,这时新数组就是排好序的。
遍历它,把它的值传给nums1即可。
/**
* @param {number[]} nums1
* @param {number} m
* @param {number[]} nums2
* @param {number} n
* @return {void} Do not return anything, modify nums1 in-place instead.
*/
var merge = function (nums1, m, nums2, n) {
let i = 0, j = 0, cur
const arr = new Array(m + n).fill(0)
while (i < m || j < n) {
if (i === m) {
cur = nums2[j++]
} else if (j === n) {
cur = nums1[i++]
} else if (nums1[i] < nums2[j]) {
cur = nums1[i++]
} else {
cur = nums2[j++]
}
arr[i + j - 1] = cur
}
for (let i = 0; i < nums1.length; i++) {
nums1[i] = arr[i]
}
};
第三种方法
第二种需要借助个新数组,因为如果直接在nums1上面操作,有可能会覆盖了nums1本身的元素。
第三种方法,思路和第二种方法类似,但是不需要借助新数组,直接在nums1上面操作
nums1后面的n位都是0,nums2也是n位,从后往前遍历不会出现覆盖的情况,我们可以从后往前遍历替换,元素相互比较,大的先排,直接覆盖nums1的值
先覆盖的0,然后往前遍历,如果覆盖到前面的元素的时候,当前的元素都已经迁移到后面了或者是本身覆盖本身,没有影响。
代码如下:
/**
* @param {number[]} nums1
* @param {number} m
* @param {number[]} nums2
* @param {number} n
* @return {void} Do not return anything, modify nums1 in-place instead.
*/
var merge = function (nums1, m, nums2, n) {
let i = m - 1, j = n - 1, cur
while (i >= 0 || j >= 0) {
if (i === -1) {
cur = nums2[j--]
} else if (j === -1) {
cur = nums1[i--]
} else if (nums1[i] < nums2[j]) {
cur = nums2[j--]
} else {
cur = nums1[i--]
}
nums1[i + j + 2] = cur
}
};