目录
一、需求
A:给定两个有序整数数组nums1和nums2,将nums2合并到nums1中,使nums1成为有序数组;
B:初始化nums1和nums2的元素数量分别为m和n;
C:假设nums1有足够多的空间来保存nums2中的元素;
二、合并后排序
2.1 思路分析
A:利用arraycopy方法,将两个数组合并为一个,然后对数组进行排序;
2.2 代码实现
public void merge(int[] nums1, int m, int[] nums2, int n) {
System.arraycopy(nums2,0,nums1,m,n);
Arrays.sort(nums1);
}
2.3 复杂度分析
A:因为底层排序是快速排序,故时间复杂度为O((n+m)log(n+m));
B:空间复杂度为O(1);
三、双指针法1
3.1 思路分析
A:新建一个数组array,将nums1中的有效数据拿出来,存放到array中;
B:然后遍历array和nums2,把较小的元素存放到nums1中;
C:遍历结束后,可能array中还有元素
a:假设array=[1,8,9],nums2=[2,5,6],nums2遍历完后,array中还有8和9,所有还要添加到nums1中;
b:添加的元素在array的起始下标为i,添加的长度为m-i;
c:添加为位置为nums1的下标为n+i时;
D:若nums2中还有元素也同理;
3.2 代码实现
public void merge(int[] nums1, int m, int[] nums2, int n) {
//新建数组
int[] array = new int[m];
//将nums1的有效数据存放到array中
System.arraycopy(nums1,0,array,0,m);
//遍历array和nums2
int i = 0;
int j = 0;
int k = 0;
while(i < m && j < n) {
if(array[i] <= nums2[j]) {
nums1[k++] = array[i++];
} else {
nums1[k++] = nums2[j++];
}
}
//遍历完仍有剩余元素
if (i < m)
System.arraycopy(array, i, nums1, i+n, m-i);
if (j < n)
System.arraycopy(nums2, j, nums1, j+m, n-j);
}
3.3 复杂度分析
A:时间复杂度为O(m+n);
B:空间复杂度为O(m);
四、双指针法2
4.1 思路分析
A:考虑到nums1后面的空间一直没有使用,我们可以把数据按照从大到小的顺序,从后往前存放到nums1中;
B:遍历比较结束后,nums2可能还有数据,都是最小的连续数了,直接放到nums1的最前面;
C:若遍历结束后,nums1有数据,这就不用管了;
4.2 代码实现
public void merge(int[] nums1, int m, int[] nums2, int n) {
//定义变量
int i = m - 1;
int j = n - 1;
int k = m + n -1;
//遍历数组
while(i >= 0 && j >= 0) {
if(nums1[i] < nums2[j]) {
nums1[k--] = nums2[j--];
} else {
nums1[k--] = nums1[i--];
}
}
//若遍历完nums2还有数据,遍历到下标j,说明长度为j+1
System.arraycopy(nums2,0,nums1,0,j+1);
}
4.3 复杂度分析
A:时间复杂度为O(m+n);
B:空间复杂度为O(1);