leetcode 精选top面试题 - 88. 合并两个有序数组

给你两个有序整数数组 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)。没有借助额外的数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值