88 合并两个有序数组
方法一 使用arraycopy排序
* 思路一:将nums2合并到nums1的尾部,再直接进行排序。
* 使用arraycopy(int[]nums1,int m,int[] nums2,int n)
* 方法来进行排序,
* 从原数组的哪个位置,移动到原数组的哪个位置,调用了多少个数
时间复杂度 O(log(n))
空间复杂度 O(1)
方法二 双指针
将nums1复制生成nums1_copy,将nums1分别与nums1_copy和nums2进行比较,如果nums1[i]的值大于等于两者,且nums[i+1]的值大于等于两者,则插入数值到nums1中
题解的解释:
比较指针p1(nums1_copy)与p2(nums2)指向的数字,将较小的数字存入nums1后,p(nums1)指针后移,直到比较完所有数字
问题
:p1和p2比较后,不需要和p指针对应的值比较吗?如果大于p指针对应的值,那么p指针不应该后移,而应该继续遍历。???
回答:第一个问题,p1的值就是p的值,只需要p1和p2进行比较。
以下是对上述代码的逐行解释:
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// 定义两个指针 p1 和 p2,分别用于遍历 nums1 和 nums2
int p1 = 0, p2 = 0;
// 创建一个新的数组 sorted 用于存储合并后的有序结果
int[] sorted = new int[m + n];
// 用于存储当前要放入 sorted 数组的元素
int cur;
// 只要 p1 没有超出 nums1 的有效部分或者 p2 没有超出 nums2 的有效部分,就继续循环
while (p1 < m || p2 < n) {
// 如果 p1 已经超出 nums1 的有效部分(即已经遍历完 nums1 的前 m 个元素)
if (p1 == m) {
// 则从 nums2 中取当前元素
cur = nums2[p2++];
// 如果 p2 已经超出 nums2 的有效部分(即已经遍历完 nums2 的 n 个元素)
} else if (p2 == n) {
// 则从 nums1 中取当前元素
cur = nums1[p1++];
// 如果 nums1 中当前指针指向的元素小于 nums2 中当前指针指向的元素
} else if (nums1[p1] < nums2[p2]) {
// 从 nums1 中取当前元素,并将 p1 指针后移
cur = nums1[p1++];
// 否则(nums2 中当前指针指向的元素小于等于 nums1 中当前指针指向的元素)
} else {
// 从 nums2 中取当前元素,并将 p2 指针后移
cur = nums2[p2++];
}
// 将当前元素放入 sorted 数组中正确的位置
sorted[p1 + p2 - 1] = cur;
}
// 将合并排序后的结果从 sorted 数组复制回 nums1 数组
for (int i = 0; i!= m + n; ++i) {
nums1[i] = sorted[i];
}
}
}
这段代码的整体思路是通过比较两个数组的元素,将较小的元素依次放入新的 sorted
数组中,最后再将 sorted
数组的内容复制回 nums1
数组,从而实现两个有序数组合并的功能。