合并两个有序数组
题目:88. 合并两个有序数组
方法一:
直接暴力将两个数组合并,然后再排序。
class Solution { public void merge(int[] nums1, int m, int[] nums2, int n) { System.arraycopy(nums2, 0, nums1, m, n); Arrays.sort(nums1); } } //arraycopy方法:五个参数分别为原数组及起始位置(要复制的)、目标数组及起始位置(要复制的),长度。
时间复杂度:O((n+m)log(n+m));
空间复杂度:O(1)。
方法二:双指针/从前往后
public void merge(int[] nums1, int m, int[] nums2, int n) { int[] ans = new int[m + n];//也可以先复制nums1数组,以它为总数组,这样空间复杂度为O(m) int p1 = 0, p2 = 0; int p = 0; while (p1 < m && p2 < n) { ans[p++] = nums1[p1] < nums2[p2] ? nums1[p1++] : nums2[p2++]; } if (p1 < m) System.arraycopy(nums1, p1, ans, p, m + n - p); if (p2 < n) System.arraycopy(nums2, p2, ans, p, m + n - p); System.arraycopy(ans, 0, nums1, 0, m + n); }
时间复杂度:O(n+m)
空间复杂度:O(m+n)
方法三:双指针/从后往前
方法二因为从头改变nums1的值,需要用其他数组先储存nums1的值。我们可以从尾部开始修改nums1的值,因为根据题意,nums1预先留有足够的空间给nums2,也就是说他后面有一大部分是空的,我们根据两数组先填满这部分就不需用额外的空间了。
public void merge(int[] nums1, int m, int[] nums2, int n) { int p1 = m - 1, p2 = n - 1; int p = m + n; while (p1 >= 0 && p2 >= 0) { nums1[p--] = nums1[p1] > nums2[p2] ? nums1[p1--] : nums2[p2--]; } System.arraycopy(nums2, 0, nums1, 0, p2 + 1);//这里:因为如果nums1还剩有元素的话,那么他们本身就位于nums1的头部,不需要重新复制,如果nums2还有元素,说明这些元素比nums1最小的元素还小,那么只需要从头开始复制剩下元素,排到nums1最前面即可。 }