【Leetcode数据结构算法题】合并两个有序数组(顺序表篇)

本文介绍了如何合并两个非递减顺序排列的整数数组,讲解了三种方法:临时数组法、临时数组倒立版和虚拟数组法,并分析了其思路和实现,重点在于探讨了在不增加额外空间复杂度的情况下,如何达到O(n+m)的时间复杂度。
摘要由CSDN通过智能技术生成

题目内容:

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

在这里插入图片描述
在这里插入图片描述

leetcode题目链接(点击即可跳转):


思路分析

看完题目,我们先别火急火燎的去编程做题,而是要先仔细理解题目的意思。(某些同学这时候可能会说“不是吧,不是吧,题目内容都给出来了,不会还有人看不懂吧?不会吧,不会吧!”)实际上,可能很多小伙伴们刚上手OJ题时(online judge 在线编程题)都不会很认真去审题,而是直接编程,然后报出一大堆错误,一个个调试,最后。。。就没有最后了,真的是“从入门到放弃~”。因此,为了避免这个问题,更加高效和正确的练习,我们应该要“理解题目—思路分析(画图理解)—极端场景—动手编程—回顾总结”。这些步骤看起来好像挺繁琐的,但是实际上花的时间比直接上手编程还要少,而且最终的学习、练习效果也要好上不少。

(当然,分享博客也可以帮助我们梳理做题的思路,总结做题的经验和方法,最最最重要的是能帮助到其他人,然刷题的这个过程多了一些“其他的意义”)


那么问题来了,如何更好的理解题目呢?
(1)将题目看完后,用自己的话复述出来,只需要大概的意思相同即可。

比如说这道题目,题目大概的意思就是“有两个整体而言升序(就是中间可能存在相等的元素,不是严格升序,这就是对”非递减排列“的理解)的数组num1,num2。num1有m个元素,但是长度为m+n,num2有n个元素,长度为n。现在要求我们将两个数组合并成一个数组并存放到num1当中,排序方式跟之前一样。”

(2)从多个角度给自己提问

比如说:
①题目有要求说不能开辟临时数组吗?或者说要求空间复杂度为O(1),又或者是原地处理数据。(显然本题是没有这个要求的!)
②题目中有说m、n不能等于0吗?如果等于0时该怎么处理?
③题目中对时间复杂度有要求吗?(进阶部分要求时间复杂度为O(n+m)

方法一:临时数组法

既然题目中没有要求“原地”合并数据,那么我们应该很容易想到建立一个长度为n+m的临时数组,先将num1,num2两个数组中的内容按照“不降序”方式放到临时数组中,然后将临时数组中的内容拷贝回num1数组中。
这种方式对于题目②出现的情况:

1)m=0、n=0 不符合题目提示中 1 <=
m+n的情况。(其实我还有点好奇如果真遇到了,m=n=0,m+n=0,怎么处理,能创建长度为0的临时数组吗?长度为0的数组有意义吗?m=0时只是代表num1中没有有效元素,但是实际的长度不为m,而是n+m >=1。如果真遇到了,都不用开辟临时数组,直接处理即可)
2)m=0、n>0,也就是说num1中无有效元素,num2中有n个有效元素,这个时候就会将num2中的数据先全部放到临时数组中,然后从数组中拷贝到num1中,可以解决问题,不会出现错误(虽然效率有点低,但好歹解决问题了,问题不大)
3)n=0、m>0,也就是说num2中无有效元素,num1中有m个有效元素,这个时候就会将num1中的数据先全部放到临时数组中,然后从数组中拷贝到num1中,可以解决问题,不会出现错误。(额,看起来呆呆的)

所以整体来看,临时数组的方式不会出现太大的问题,这个时候就可以画出图解,编写代码测试了。


算法图解

在这里插入图片描述


函数接口实现

void merge(int* nums1, int nums1Size, int m, 
int* nums2, int nums2Size, int n){
   
    int* arr = (int*)malloc((m+n)*sizeof(int));//创建长度为m+n的临时变量
    int src1 = 0;//nums1的起始下标
    
  • 27
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大家好我叫张同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值