给你两个有序整数数组 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]
提示:
-10^9 <= nums1[i], nums2[i] <= 10^9 nums1.length == m + n nums2.length == n
思路一:双指针,从后往前归并
双指针从后往前归并,两个数组均从数组尾部开始遍历,
遍历数组,把两个数组尾部元素的较大者放到num1中。
循环结束时,如果数组num1还有元素,不需要管;如果数组num2还有元素,直接复制到num1数组中
1 class Solution { 2 public void merge(int[] nums1, int m, int[] nums2, int n) { 3 // 双指针,两个数组均从数组尾部开始遍历 4 // 把两个数组尾部元素的较大者放到num1中 5 int p = m - 1, q = n - 1; 6 int len = m + n; 7 int index = len - 1; // 指向下个排序元素应该存放的下标 8 while(p >= 0 && q >= 0){ 9 if(nums1[p] >= nums2[q]){ 10 nums1[index--] = nums1[p--]; 11 }else{ 12 nums1[index--] = nums2[q--]; 13 } 14 } 15 // 如果数组num1还有元素,不需要管 16 // 如果数组num2还有元素,直接复制到num1数组中 17 while(q >= 0){ 18 nums1[index--] = nums2[q--]; 19 } 20 } 21 }
leetcode 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户,内存消耗:38.8 MB, 在所有 Java 提交中击败了40.28%的用户
复杂度分析:
时间复杂度:O(n+m)。对两个数组都进行了一次遍历,所以时间复杂度为O(n+m)。
空间复杂度:O(1)。因为不需要借助额外的数组空间,所以空间复杂度为O(1)。
思路二:
将两个数组合并后排序, 虽然编码简单,但是效率较低
1 class Solution { 2 public void merge(int[] nums1, int m, int[] nums2, int n) { 3 // 合并两个数组后排序 4 System.arraycopy(nums2, 0, nums1, m, n); 5 Arrays.sort(nums1); 6 } 7 }
leetcode 执行用时:1 ms, 在所有 Java 提交中击败了25.25%的用户, 内存消耗:38.6 MB, 在所有 Java 提交中击败了70.84%的用户
复杂度分析:
时间复杂度:O(log(m+n))。拷贝数组的时间开销为O(m), 排序的时间花费是O(log(m+n))。
空间复杂度:O(1)。没有借助额外的数组。