题目
给你两个有序整数数组 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]
提示:
-10^9 <= nums1[i], nums2[i] <= 10^9
nums1.length == m + n
nums2.length == n
分析
以升序为例
需要注意的是num1和num2都已经是有序的了。
所以我们只需要取出num1和num2的值进行比较。将大的值往num1的右边放就行。不需要考虑自己内部的大小了。
由于num1后半部是空的,所以从num1后往前填充值是最合适的。即每次取出num1和num2最大值往num1右侧填充。
代码实现
需要记录num1前m个当前取出的位置和num2当前取出的位置。
由于是取最大值所以角标从最后开始。
//num1起始取值的位置
int num1Index = m-1;
//num2起始取值的位置
int num2Index = n-1;
//当前已经存储到的位置
int cur = n + m -1;
每次从num1和num2中取出一个进行对比,大的值放到cur位置。同时cur--。
同时胜出的numIndex--。
if (nums1[num1Index]<nums2[num2Index]){
nums1[cur--]=nums2[num2Index--];
}else{
nums1[cur--]=nums1[num1Index--];
}
接下来就是不停的重复这个过程。寻找结束条件
如果num1先取完,就需要将num2剩余的都挨个取出放入num1剩余位置。
而如果num2先取完,就直接可以结束了。为啥呢,因为剩余的数据本来就正好是num1中的数据。
所以可以使用下面这种先判断nums是否取完的讨巧写法。
//num2取完直接结束
while (num2Index>=0) {
//num1先取完,就需要将num2剩余的都挨个取出放入num1剩余位置。
if (num1Index>=0&&nums1[num1Index] > nums2[num2Index]) {
nums1[cur--] = nums1[num1Index--];
} else {
nums1[cur--] = nums2[num2Index--];
}
}
下面是全部代码:
public class _88_MergeSortedArray {
public void merge(int[] nums1, int m, int[] nums2, int n) {
//num1起始取值的位置
int num1Index = m-1;
//num2起始取值的位置
int num2Index = n-1;
//当前已经存储到的位置
int cur = n + m -1;
//num2取完直接结束
while (num2Index>=0) {
//num1先取完,就需要将num2剩余的都挨个取出放入num1剩余位置。
if (num1Index>=0&&nums1[num1Index] > nums2[num2Index]) {
nums1[cur--] = nums1[num1Index--];
} else {
nums1[cur--] = nums2[num2Index--];
}
}
}
}