88.有序数组合并
问题描述:
分析:
题目要求将两个数组合并为一个有序数组,不使用额外的内存空间。
- 首先容易想到的就是将nums2顺次插入到nums1的末尾,再对nums1进行快速排序,这样的时间复杂度是O(n+log2(m+n))。
- 考虑到两个数组都是有序数组,所以可以在对nums2进行插入操作之前,将待插入的元素与nums1中元素进行逐个比较,通过指针滑动将待插入元素插到合适的位置,这样每次插入后的数组都是有序的。这里不选择从前往后插入,因为当数组前部有元素插入的话,插入位置之后的所有元素都要进行一次内存交换。
选择从后往前插入,三个指针index1,index2,indexMerged分别指向nums1的末尾,nums2的末尾,合并后数组的末尾。对nums2遍历,比较index1和index2所指元素,将较大的移动至indexMerged的位置,插入后指针向前滑动,直到index1 == 0 && index2 == 0 ,遍历结束。这样的时间复杂度最坏情况下为O(m+n)
综合上面的两种做法,如果待排序的数组很大,可以选择第一种做法,且这种做法也适用于无序数组的排序。但是如果数组较小,且是有序数组的话,就可以考虑第二种做法了。
代码如下:
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int index1 = m - 1;
int index2 = n - 1;
int indexMerged = (m+n) - 1;
while (index1 >= 0 && index2 >= 0) {
if (nums1[index1] > nums2[index2]) {
nums1[indexMerged--] = nums1[index1--];
} else {
nums1[indexMerged--] = nums2[index2--];
}
}
while (index2 >= 0) {
nums1[indexMerged--] = nums2[index2--];
}
}
}