0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何求递归算法的时间复杂度

算法与数据结构 来源:代码随想录 作者:代码随想录 2022-07-13 11:30 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

本篇通过一道面试题,一个面试场景,来好好分析一下如何求递归算法的时间复杂度。

相信很多同学对递归算法的时间复杂度都很模糊,那么这篇Carl来给大家通透的讲一讲。

同一道题目,同样使用递归算法,有的同学会写出了O(n)的代码,有的同学就写出了O(logn)的代码

这是为什么呢?

如果对递归的时间复杂度理解的不够深入的话,就会这样!

那么我通过一道简单的面试题,模拟面试的场景,来带大家逐步分析递归算法的时间复杂度,最后找出最优解,来看看同样是递归,怎么就写成了O(n)的代码。

面试题:求x的n次方

想一下这么简单的一道题目,代码应该如何写呢。最直观的方式应该就是,一个for循环求出结果,代码如下:

intfunction1(intx,intn){
intresult=1;//注意任何数的0次方等于1
for(inti=0;i< n; i++) {
        result = result * x;
    }
    returnresult;
}

时间复杂度为O(n),此时面试官会说,有没有效率更好的算法呢。

如果此时没有思路,不要说:我不会,我不知道了等等

可以和面试官探讨一下,询问:“可不可以给点提示”。面试官提示:“考虑一下递归算法”。

那么就可以写出了如下这样的一个递归的算法,使用递归解决了这个问题。

intfunction2(intx,intn){
if(n==0){
return1;//return1同样是因为0次方是等于1的
}
returnfunction2(x,n-1)*x;
}

面试官问:“那么这个代码的时间复杂度是多少?”。

一些同学可能一看到递归就想到了O(logn),其实并不是这样,递归算法的时间复杂度本质上是要看:递归的次数 * 每次递归中的操作次数

那再来看代码,这里递归了几次呢?

每次n-1,递归了n次时间复杂度是O(n),每次进行了一个乘法操作,乘法操作的时间复杂度一个常数项O(1),所以这份代码的时间复杂度是 n * 1 = O(n)。

这个时间复杂度就没有达到面试官的预期。于是又写出了如下的递归算法的代码:

intfunction3(intx,intn){
if(n==0){
return1;
}
if(n%2==1){
returnfunction3(x,n/2)*function3(x,n/2)*x;
}
returnfunction3(x,n/2)*function3(x,n/2);
}

面试官看到后微微一笑,问:“这份代码的时间复杂度又是多少呢?” 此刻有些同学可能要陷入了沉思了。

我们来分析一下,首先看递归了多少次呢,可以把递归抽象出一颗满二叉树。刚刚同学写的这个算法,可以用一颗满二叉树来表示(为了方便表示,选择n为偶数16),如图:

fc74a264-025a-11ed-ba43-dac502259ad0.png

当前这颗二叉树就是求x的n次方,n为16的情况,n为16的时候,进行了多少次乘法运算呢?

这棵树上每一个节点就代表着一次递归并进行了一次相乘操作,所以进行了多少次递归的话,就是看这棵树上有多少个节点。

熟悉二叉树话应该知道如何求满二叉树节点数量,这颗满二叉树的节点数量就是2^3 + 2^2 + 2^1 + 2^0 = 15,可以发现:这其实是等比数列的求和公式,这个结论在二叉树相关的面试题里也经常出现

这么如果是求x的n次方,这个递归树有多少个节点呢,如下图所示:(m为深度,从0开始)

fc93b21c-025a-11ed-ba43-dac502259ad0.png

时间复杂度忽略掉常数项-1之后,这个递归算法的时间复杂度依然是O(n)。对,你没看错,依然是O(n)的时间复杂度!

此时面试官就会说:“这个递归的算法依然还是O(n)啊”, 很明显没有达到面试官的预期。

那么O(logn)的递归算法应该怎么写呢?

想一想刚刚给出的那份递归算法的代码,是不是有哪里比较冗余呢,其实有重复计算的部分。

于是又写出如下递归算法的代码:

intfunction4(intx,intn){
if(n==0){
return1;
}
intt=function4(x,n/2);//这里相对于function3,是把这个递归操作抽取出来
if(n%2==1){
returnt*t*x;
}
returnt*t;
}

再来看一下现在这份代码时间复杂度是多少呢?

依然还是看他递归了多少次,可以看到这里仅仅有一个递归调用,且每次都是n/2 ,所以这里我们一共调用了log以2为底n的对数次。

每次递归了做都是一次乘法操作,这也是一个常数项的操作,那么这个递归算法的时间复杂度才是真正的O(logn)

此时大家最后写出了这样的代码并且将时间复杂度分析的非常清晰,相信面试官是比较满意的。

总结

对于递归的时间复杂度,毕竟初学者有时候会迷糊,刷过很多题的老手依然迷糊。

本篇我用一道非常简单的面试题目:求x的n次方,来逐步分析递归算法的时间复杂度,注意不要一看到递归就想到了O(logn)!

同样使用递归,有的同学可以写出O(logn)的代码,有的同学还可以写出O(n)的代码。

对于function3 这样的递归实现,很容易让人感觉这是O(logn)的时间复杂度,其实这是O(n)的算法!

intfunction3(intx,intn){
if(n==0){
return1;
}
if(n%2==1){
returnfunction3(x,n/2)*function3(x,n/2)*x;
}
returnfunction3(x,n/2)*function3(x,n/2);
}

可以看出这道题目非常简单,但是又很考究算法的功底,特别是对递归的理解,这也是我面试别人的时候用过的一道题,所以整个情景我才写的如此逼真,哈哈。

大厂面试的时候最喜欢用“简单题”来考察候选人的算法功底,注意这里的“简单题”可并不一定真的简单哦!

如果认真读完本篇,相信大家对递归算法的有一个新的认识的,同一道题目,同样是递归,效率可是不一样的!

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算法
    +关注

    关注

    23

    文章

    4761

    浏览量

    97167
  • 代码
    +关注

    关注

    30

    文章

    4942

    浏览量

    73163
  • 递归
    +关注

    关注

    0

    文章

    29

    浏览量

    9264
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    免停电接线的电能质量在线监测装置的安装和调试复杂吗?

    免停电接线的电能质量在线监测装置 整体安装调试复杂度较低 ,远低于传统停电接线模式,其中低压系统可实现 “快速部署、简易调试”,中高压系统因需专业工具与资质,复杂度略有提升,但仍能通过标准化流程降低
    的头像 发表于 12-05 18:00 3334次阅读
    免停电接线的电能质量在线监测装置的安装和调试<b class='flag-5'>复杂</b>吗?

    基于DSP与FPGA异构架构的高性能伺服控制系统设计

    DSP+FPGA架构在伺服控制模块中的应用,成功解决了高性能伺服系统对实时性、精度和复杂度的多重需求。通过合理的功能划分,DSP专注于复杂算法和上层控制,FPGA处理高速硬件任务,两者协同实现了传统架构难以达到的性能指标。
    的头像 发表于 12-04 15:38 162次阅读
    基于DSP与FPGA异构架构的高性能伺服控制系统设计

    程序运行慢,是否需检查算法时间复杂度过高?

    程序运行慢,需检查算法时间复杂度是否过高?
    发表于 11-17 08:08

    程序运行速度很慢如何优化?

    ;gt;外设,内存<->内存)交给DMA,释放CPU资源。 优化算法: 选择时间复杂度更低的算法。避免不必要的循环和重复计算。 减少函数调用开销: 对于频繁调用的小函数
    发表于 11-17 06:12

    复杂的软件算法硬件IP核的实现

    看到整个实现只有一个状态“S0”。 对于有复杂时序要求的操作,例如加密算法里面常见的 for 循环结构,在生成 begin 和 end 之间就会有多个状态,每个状态都对应与某个组合逻辑的特定的连接方式
    发表于 10-30 07:02

    基于 SRT4 的整数除法器的优化

    产生超大的面积,得不偿失。为了缩短运算周期,可以使用基数为4的数位递归SRT算法(每次迭代结果为2位),模拟基64的SRT算法,每个循环重复多次,每个周期进行3次迭代,即6位/周期,等效于基数为64
    发表于 10-23 07:23

    Booth编码的原理及选择

    }的部分积,数目减少了一半。P中仅有5个元素,大大减轻了多路选择的负担,且2M可以通过1位左移操作产生,很好的实现了部分积个数与Р中元素的生成和选择之间的平衡。因此结构相对比较简单,硬件复杂度不大,是目前最广泛使用的部分积生成算法
    发表于 10-22 07:53

    e203除法器算法改进(二)

    表示余数) 利用数学递归算法进行将除法操作简化为迭代算法,每次迭代产生一个基数为$beta$的商。经过$j$次迭代后,产生的商值表示为: q{j}=sum{i=0}^j q_i beta^{j-i
    发表于 10-22 06:11

    NTT设计介绍

    去乘以另一个数据的每一位,其算法时间复杂度为。NTT可以看作是定义在有限域上的快速傅里叶变换,算法时间
    发表于 10-22 06:05

    电能质量在线监测装置的精度等级和准确的关系是否受测量参数的影响?

    电能质量在线监测装置的精度等级和准确的关系 会显著受测量参数影响 ,核心原因在于:不同电能质量参数(如电压有效值、谐波、闪变、暂升 / 暂降)的 测量原理复杂度、硬件依赖算法要求
    的头像 发表于 09-12 10:02 488次阅读
    电能质量在线监测装置的精度等级和准确<b class='flag-5'>度</b>的关系是否受测量参数的影响?

    时间同步设备在复杂网络环境中的调试要点

    时间同步设备是保障网络系统协同运行的基础设施,尤其在金融、电力、通信等领域对精度要求较高的场景中,其稳定性直接影响业务连续性。在实际部署中,网络环境的复杂性常给同步精度带来挑战。本文将分享几个调试过程中的经验要点。
    的头像 发表于 08-13 15:48 303次阅读
    <b class='flag-5'>时间</b>同步设备在<b class='flag-5'>复杂</b>网络环境中的调试要点

    LABVIEW递归获取列表显示到树形结构

    我这个递归我逻辑没问题啊!我断点调试看了,是因为重入VI执行没有把树形结构里面节点传入到下一个递归调用,进入重调用的时候我看了树形结构里面节点是空的。第一次写入的节点并没有传入到下一次递归。 反正很
    发表于 08-07 17:59

    ADIN2111集成10BASE-T1L PHY的低复杂度、2端口以太网交换机技术手册

    ADIN2111是一款低功耗、低复杂度、双以太网端口交换机,它集成了10BASE-T1L PHY和一个串行外设接口(SPI)端口。该器件使用低功率受限节点,面向工业以太网应用且符合IEEE
    的头像 发表于 05-15 11:41 1226次阅读
    ADIN2111集成10BASE-T1L PHY的低<b class='flag-5'>复杂度</b>、2端口以太网交换机技术手册

    AI时代下芯片复杂度飙升,思尔芯国产硬件仿真加速芯片创新

    引言在人工智能(AI)技术蓬勃发展的今天,芯片的复杂度正以前所未有的速度飙升,轻松跨越了百亿逻辑门级别的大关。这一趋势不仅推动了半导体行业的快速发展,也对硬件仿真系统提出了更高的挑战和要求。在近日
    的头像 发表于 12-27 18:01 1187次阅读
    AI时代下芯片<b class='flag-5'>复杂度</b>飙升,思尔芯国产硬件仿真加速芯片创新

    芯片设计复杂度剧增,紫光芯片云 3.0 助力企业搭建专业设计环境

    。   实际上,国内中小IC设计企业居多,而如今他们面临更加复杂的设计需求。随着芯片制程和规模要求不断提高,芯片设计环境所需资源越来越大,设计环境构建更加复杂,初创企业如何搭建设计环境,中小企业如何在人员经验欠缺的情况下完成有效布局,又如
    的头像 发表于 12-26 17:04 1954次阅读
    芯片设计<b class='flag-5'>复杂度</b>剧增,紫光芯片云 3.0 助力企业搭建专业设计环境