文章目录
题目
问题描述1:
合并两个有序数组
两个有序整数数组nums1和nums2,将nums2合并到nums1中,使nums1成为一个有序数组。
- 初始化nums1和nums2的元素数量分别为m和n。
- 假设nums1的空间大小等于m+n,这样它就有足够的空间保存来自nums2的元素。
例如:
输入:
nums1 = [1, 2, 3, 5, 7, 9, 0, 0, 0, 0] ,m = 6;
nums2 = [2, 4, 6, 8] , n = 4;
输出:[1, 2, 2, 3, 4, 5, 6, 7, 8, 9]
一、思路
1.排序算法
时间复杂度 O( (n+m)log(n+m) )。
先合并两个数组,然后再使用排序算法。
2.双指针法使用空间复杂度优化时间复杂度***
时间复杂度O(n+m),空间复杂度O(n)。
- 创建一个新的数组copy_nums1,用于存储num1的有效元素。
- 定义p,p1,p2三个指针,分别指向nums1,copy_nums1,nums2;
- 遍历copy_nums1,nums2两个数组,将元素有序的放进nums1中。
3.双指针法优化空间复杂度和时间复杂度***
时间复杂度O(n+m),空间复杂度O(1)。
从后往前遍历。
- 创建三个指针:p表示nums1从后往前要插入的位置,p1表示nums1的有效元素的位置,p2表示nums2的有效元素的位置。
- 遍历nums1,nums2两个数组的有效元素,将元素从后往前有序的放进nums1中。
二、代码
1.使用排序算法
代码如下:
/**
* 时间复杂度 O( (n+m)log(n+m) )
*
* @param nums1 数组1
* @param m 数组1有效元素的个数
* @param nums2:数组2
* @param n: 数组2有效元素个数
* @return 合并后的数组
*/
public static int[] merge(int[] nums1, int m, int[] nums2, int n) {
System.arraycopy(nums2, 0, nums1, m, n); // nums1=[1,2,3,5,7,9,2,4,6,8]
Arrays.sort(nums1); // [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]
return nums1;
}
2.双指针法使用空间复杂度优化时间复杂度******
代码如下:
/**
* 双指针法
* 使用空间复杂度优化时间复杂度
* 时间复杂度O(m+n),空间复杂度O(n)
* @param nums1 数组1
* @param m 数组1有效元素的个数
* @param nums2 数组2
* @param n 数组2有效元素个数
* @return 合并后的数组
*/
public static int[] merge1(int[] nums1, int m, int[] nums2, int n) {
int[] copy_nums1 = new int[m];
System.arraycopy(nums1, 0, copy_nums1, 0, m); // 将nums1拷贝到copy_nums1中
int p1 = 0; // 指向copy_nums1
int p2 = 0; // 指向nums2
int p = 0; // 指向nums1
while (p1 < m && p2 < n) {
nums1[p++] = copy_nums1[p1] > nums2[p2] ? nums2[p2++] : copy_nums1[p1++];
}
if (p1 < m) {
// copy_nums1 没有复制完
System.arraycopy(copy_nums1, p1, nums1, p1 + p2, m + n - p1 - p2);
}
if (p2 < n) {
//nums2没有复制完
System.arraycopy(nums2, p2, nums1, p1 + p2, m + n - p1 - p2);
}
return nums1;
}
3.双指针法优化空间复杂度和时间复杂度******
代码如下:
/**
* 双指针法
* 将空间复杂度优化为O(1)
* 时间复杂度O(m+n)
* 从后往前遍历
* @param nums1 数组1
* @param m 数组1有效元素的个数
* @param nums2 数组2
* @param n 数组2有效元素个数
* @return 合并后的数组
*/
public static int[] merge2(int[] nums1, int m, int[] nums2, int n) {
int p1 = m - 1; // 指向copy_nums1
int p2 = n - 1; // 指向nums2
int p = m + n - 1; // 指向nums1
while (p1 >= 0 && p2 >= 0) {
nums1[p--] = nums1[p1] > nums2[p2] ? nums1[p1--] : nums2[p2--];
}
//nums2没有复制完
System.arraycopy(nums2, 0, nums1, 0, p2+1);
return nums1;
}