「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」
前言
力扣第八十八题 合并两个有序数组
如下所示:
给你两个按 非递减顺序 排列的整数数组 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
的初始长度为 m+n
这表示我们只需要将 nums2
中的 n
个元素插入其中即可。这也正符合题目中要求的,将修改的内容存储在 nums1
中。
这一题我是经过许多次 Debug
后才正确写出来的,所以同志们,碰到没通过的用例,调试才是唯一的真理啊。
因为要合并 nums1
和 nums2
,我们可以用两个临时变量 n1
和 n2
表示我们当前取到了第几个元素了。在遍历的过程中只有出现 大于 的情况才需要将 nums1
的元素后移。
大致的步骤如下所示:
- 遍历整个
nums1
- 如果
nums1
中的元素没有用完,且当前元素的值大于nums2
的值时。我们将nums1
剩余的元素后移一位,即nums[i, m]
移动到nums[i+1, m+n2]
- 遍历结束返回结果即可
举个例子
此处以示例中的 nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
作为例子
- 遍历
nums1
,当i = 0
时,nums1[0] < nums2[1]
,将计数n1++, n1 = 1
- 当
i = 1
时,nums1[1] == nums2[0]
,再将计数n1++, n1 = 2
- 当
i = 2
时,nums1[2] > nums2[0]
,再nums1
后面的元素后移一位,nums1
变为了[1,2,3,3,0,0]
,再将nums2[0]
插入到第2
个位置,nums1
变为了[1,2,2,3,0,0]
。将计数n2++, n2 = 1
- 当
i = 3
时,nums1[3] < nums2[1]
,再将计数n1++, n1 = 3
- 当
i = 4, 5
时,nums1
的元素用完了,故直接插入nums2
的元素即可 - 返回最终的结果
[1, 2, 2, 3, 5, 6]
即可
二、实现
实现代码
实现代码与思路中保持一致
public void merge(int[] nums1, int m, int[] nums2, int n) {
int n1 = 0, n2 = 0;
for (int i =0; i<nums1.length; i++) {
if (n1 >= m) { // nums1中的元素用完了
nums1[i] = nums2[n2];
n2++;
} else if (n2 < n && nums1[i] > nums2[n2]) { // 只有nums2中有元素,且当前元素大于才需要后移
// 从后向前,将nums1中的位置向后移动一个位置
for (int j=m+n2; j>i; j--) {
nums1[j] = nums1[j-1];
}
nums1[i] = nums2[n2];
n2++;
} else {
n1++;
}
}
}
测试代码
public static void main(String[] args) {
int[] nums1 = {1,2,3,0,0,0};
int[] nums2 = {2,5,6};
new Number88().merge(nums1, 3, nums2, 3);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~