【LeetCode】合并两个有序数组(88. 题)| 数组、逆向双指针归并 | 图解算法

(1)题目描述

image-20210819115914948

image-20210819115937852

LeetCode链接:合并两个有序数组

(2)解题思路

1)思路1:合并后排序

  1. 将数组 nums2 放到数组 nums1 的尾部,

  2. 然后用 qsort 函数对整个数组进行排序。

  • 时间复杂度:O((m+n)log(m+n)),qsort 函数快速排序的时间复杂度为nlogn
  • 空间复杂度:O(1)

2)思路2:归并到新数组

  1. 开辟一个长度为 m+n 的新数组,

  2. 设置两个指针 p1 和 p2 从前往后遍历数组 nums1 和 nums2 ,初始分别指向 nums1 和 nums2 的头部,

  3. 每次比较 p1 和 p2 指向位置的数值,取出较小的从前往后依次放到新数组中。

  4. 再将新数组中的元素依次拷贝到 nums1 中

  • 时间复杂度:O(m+n)
  • 空间复杂度:O(m+n)
image-20210819213528295

3)思路3:逆向双指针

  1. 从后面开始确定,从后向前遍历数组,

  2. 设置指针 p1 和 p2 分别指向 nums1 和 nums2 的有效数字的尾部,从尾部向前一边比较一边遍历,再设置指针 dst 指向 nums1 的尾部,

  3. 每次比较完 p1 和 p2 指向位置的数值大小后,通过 dst 从后往前填充,每次取两者之中的较大者放到 nums1 的最后面。

  • 时间复杂度:O(m+n)
  • 空间复杂度:O(1)
    image-20210819213700217

因为两个数组长度不一样,数据不一样,不知道哪一个指针先结束,还需要考虑到这两种情况:

(1)nums1 的指针 p1 先遍历完,指针 p2 还没有遍历完,此时还需要把 nums2 的数据挪过去

image-20210819214806592

(2)nums2 的指针 p2 先遍历完,就不用处理了,因为剩下的数本来就在nums1里面

image-20210819215107925

代码如下:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    //p1和p2分别指向数组nums1和nums2的有效数字的尾部
    int p1 = m - 1;
    int p2 = n - 1;
    //dst指向数组nums1的尾部
    int dst = m + n - 1;
    //从后往前依次比较p1和p2指向位置的元素的大小
    while(p1 >= 0 && p2 >= 0)  //p1和p2有一个遍历完,则结束循环
    {
        if(nums1[p1] >= nums2[p2])
        {
            nums1[dst--] = nums1[p1--];
        }
        else if(nums1[p1] < nums2[p2])
        {
            nums1[dst--] = nums2[p2--];
        }
    }
    //如果是p2先遍历完,就不用处理,因为剩下的数本来就在nums1里面
    
    //如果p1先遍历完,p2还没有遍历完,则需要把nums2的数据挪过去
    while(p1 < 0 && p2 >=0)
    {
        nums1[dst--] = nums2[p2--];
    }
}

大家快去动手练习一下吧!

  • 20
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 21
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值