给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
- 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
- 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
第一种思路:直接将两个数组合并,再对这个数组直接排序。时间复杂度:O(nlogn),空间复杂度:O(n)
public void merge(int[] nums1,int m,int[] nums2,int n) {
for(int i = 0;i < n;i++) {
nums1[m++] = nums2[i];
}
Arrays.sort(nums1);
}
第二种其实也是第一种的改良,只不过想复习下冒泡排序算法:
public void merge3(int[] nums1,int m,int[] nums2,int n) {
/*
* 算是冒泡排序的改良版吧,考虑到如果后半部分有序,那么只排前半部分就好了
*/
int temp = 0;
int lastExcheangeIndex = 0; //记录最近交换的 j, 如果把数组看成是两部分,一部分排好,一部分未排,这个也就是左半部分未排序的边界
int sortBorder = nums1.length-1;
for(int i = 0;i < n;i++) {
nums1[m++] = nums2[i];
}
for(int i = 0;i < nums1.length;i++) {
boolean isSorted = true; //用标记记录是否有序了,有序的话就不用循环了
for(int j = 0; j < sortBorder;j++) {
if(nums1[j] > nums1[j+1]) {
temp = nums1[j];
nums1[j] = nums1[j+1];
nums1[j+1] = temp;
isSorted = false;
lastExcheangeIndex = j;
}
}
sortBorder = lastExcheangeIndex;
if(isSorted) {
break;
}
}
}
大神思路:采用归并排序的思路,分别比较两数组中的值,将较小的数赋值给重设的数组,最后将排好序的赋值给 nums1。
代码:
public static void merge0(int[] nums1,int m,int[] nums2,int n) {
//使用归并的思想进行合并数组
int pos = 0;
int[] res = new int[nums1.length]; //重设数组存放比较后的数,最后再整体赋值给原数组。
int mpos = 0,npos = 0; //mpos 代表的是 nums1 数组的和 nums2 比较的下标。
while(mpos < m || npos <n) {
if(mpos < m && npos < n) { //如果在两个原数组中比较的下标小于数组含有元素的长度,则进行比较和赋值。
if(nums1[mpos] <= nums2[npos]) {
res[pos] = nums1[pos];
pos++;
mpos++;
}else {
res[pos] = nums2[npos];
pos++;
npos++;
}
continue;
}
if(mpos == m) { //如果某一个原数组已经赋值完的话,就把另一个原数组的值赋值给 res[] 后面。
res[pos] = nums2[npos];
pos++;
npos++;
continue;
}
if(npos == n) {
res[pos] = nums2[mpos];
pos++;
mpos++;
continue;
}
}
for(int i = 0;i < m+n;i++) { // 最后将合并好的数组赋值给 nums1。
nums1[i] = res[i];
}
}