本题 题目链接
题目描述
我的题解
!!!记住:一般而言,对于有序数组可以通过 双指针法 达到 O(n + m) 的时间复杂度。
(要开辟新空间的方法就不说了)
方法:双指针(从后往前)
思路分析
- 不开辟新空间,直接在 nums1 数组上操作。
- 一般而言我们会想到从前往后分别遍历 nums1 和 nums2。但是这样的话,交换数字之类的超麻烦,似乎也不容易实现!
- 那么,既然能从前往后,反正又是有序数组,那我也能从后往前呀,似乎并没有啥区别。能前往后,自然也能后往前嘛。
- 而前往后的缺点就是空间不够。那后往前呢?我们最终是要把 nums2 放进 nums1 里的,那 nums1 后面不是还有 n 个位置的空间嘛!空间这么多,就不怕交换位置造成的麻烦啦!
- 指针 i、j 分别指向 nums1、nums2 最后一个元素,而 cur 指针为当前可以放入的位置。
时间复杂度:O(n+m)
空间复杂度:O(1)
代码如下
public void merge(int[] nums1, int m, int[] nums2, int n) {
if (n == 0 || nums2 == null || nums1 == null) return;
if (m == 0) {
if (nums2 != null) {
for (int i = 0; i < n; i++)
nums1[i] = nums2[i];
}
return;
}
int i = m - 1;
int j = n - 1;
int cur = m + n - 1;
while (j >= 0) {
if (nums1[i] > nums2[j]) {
nums1[cur--] = nums1[i--];
} else {
nums1[cur--] = nums2[j--];
}
if (i == -1) { // num1前m个元素的遍历结束了
while (j != -1) nums1[cur--] = nums2[j--];
}
}
// System.out.println(Arrays.toString(nums1));
}