[LeetCode] 88. 合并两个有序数组
Posted arcsinW
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] 88. 合并两个有序数组相关的知识,希望对你有一定的参考价值。
Description
给你两个有序整数数组?nums1 和 nums2,请你将 nums2 合并到?nums1?中,使 nums1 成为一个有序数组。
说明:
初始化?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]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Analyse
合并两个有序数组nums1和nums2,nums1的空间够放下nums2,不用开新的数组存结果
归并排序(Merge sort)
完整版的归并排序在这里不是最优解,因为数组的两部分已经有序了,可以直接双指针法开始merge,但这道题是个练习归并排序的好地方
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// 先将 nums2 append 到 nums1
// public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
System.arraycopy(nums2, 0, nums1, nums1.length - nums2.length, nums2.length);
int low = 0, high = nums1.length - 1;
// merge sort
mergeSort(nums1, low, high);
}
// 将数组拆分成两部分,直到有序
private void mergeSort(int[] nums, int low, int high) {
// base case
if (low >= high) return;
int mid = low + (high - low) / 2; // 不用(low + high) / 2 防止加法溢出
mergeSort(nums, low, mid);
mergeSort(nums, mid+1, high);
merge(nums, low, mid, high);
}
// 合并两个有序数组(或数据的两个有序部分)
private void merge(int [] nums, int low, int mid, int high) {
// 双指针法
int p = low, q = mid + 1;
// 需要一个临时空间
int[] tmpNums = new int[high - low + 1];
int index = 0;
while (p <= mid && q <= high) {
if (nums[p] < nums[q]) {
tmpNums[index++] = nums[p++];
} else {
tmpNums[index++] = nums[q++];
}
}
while (p <= mid) {
tmpNums[index++] = nums[p++];
}
while (q <= high) {
tmpNums[index++] = nums[q++];
}
// 将排好序的值写回nums
System.arraycopy(tmpNums, 0, nums, low, high - low + 1);
}
}
将merge()改成下面这样就能击败100%了,时间复杂度O(n + m);空间复杂度O(n + m),空间复杂度还可以继续优化,只需要把nums1中的元素复制出来一份就行了O(m),再继续优化可以两个有序数组逆序比较,这样只需要O(1)
public void merge(int[] nums1, int m, int[] nums2, int n) {
// 先将 nums2 append 到 nums1
System.arraycopy(nums2, 0, nums1, m, n);
// int low = 0, high = m - 1;
// merge sort
// mergeSort(nums1, low, high);
merge(nums1, 0, m - 1, m + n - 1);
}
以上是关于[LeetCode] 88. 合并两个有序数组的主要内容,如果未能解决你的问题,请参考以下文章