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

    文章

    4610

    浏览量

    92859
  • 代码
    +关注

    关注

    30

    文章

    4786

    浏览量

    68563
  • 递归
    +关注

    关注

    0

    文章

    28

    浏览量

    9013
收藏 人收藏

    评论

    相关推荐

    【「从算法到威廉希尔官方网站 —数字芯片算法的威廉希尔官方网站 实现」阅读体验】+内容简介

    内容简介这是一本深入解读基础算法及其威廉希尔官方网站 设计,以打通算法研发到数字IC设计的实现屏障,以及指导芯片设计工程师从底层掌握复杂威廉希尔官方网站 设计与优化方法为目标的专业技术书。任何芯片(如WiFi芯片、5G芯片
    发表于 11-21 17:14

    NPU与机器学习算法的关系

    在人工智能领域,机器学习算法是实现智能系统的核心。随着数据量的激增和算法复杂度的提升,对计算资源的需求也在不断增长。NPU作为一种专门为深度学习等机器学习任务设计的处理器,其与机器学习算法
    的头像 发表于 11-15 09:19 450次阅读

    时间复杂度为 O(n^2) 的排序算法

    作者:京东保险 王奕龙 对于小规模数据,我们可以选用时间复杂度为 O(n2) 的排序算法。因为时间复杂度并不代表实际代码的执行
    的头像 发表于 10-19 16:31 1150次阅读
    <b class='flag-5'>时间</b><b class='flag-5'>复杂度</b>为 O(n^2) 的排序<b class='flag-5'>算法</b>

    浅谈Vivado编译时间

    随着FPGA规模的增大,设计复杂度的增加,Vivado编译时间成为一个不可回避的话题。尤其是一些基于SSI芯片的设计,如VU9P/VU13P/VU19P等,布局布线时间更是显著增加。当然,对于一些设计而言,十几个小时是合理的。但
    的头像 发表于 09-18 10:43 915次阅读
    浅谈Vivado编译<b class='flag-5'>时间</b>

    PCB与PCBA工艺复杂度的量化评估与应对措施

    一站式PCBA智造厂家今天为大家讲讲PCBA工艺复杂吗?PCBA工艺的复杂性应对PCBA工艺复杂性的措施。在电子制造领域,PCBA工艺是至关重要的环节。尽管对许多人来说,PCBA工艺可能看似
    的头像 发表于 09-13 09:21 404次阅读

    业务复杂度治理方法论--十年系统设计经验总结

    复杂度量公式        子模块的复杂度cp乘以该模块对应的开发时间权重值tp,累加后得到系统的整体复杂度C 这里的子模块复杂度 c
    的头像 发表于 09-05 14:11 990次阅读
    业务<b class='flag-5'>复杂度</b>治理方法论--十年系统设计经验总结

    Python递归的经典案例

    当我们碰到诸如需要求阶乘或斐波那契数列的问题时,使用普通的循环往往比较麻烦,但如果我们使用递归时,会简单许多,起到事半功倍的效果。这篇文章主要和大家分享一些和递归有关的经典案例,结合一些资料谈一下个人的理解,也借此加深自己对递归
    的头像 发表于 08-05 15:57 336次阅读

    CISC(复杂指令集)与RISC(精简指令集)的区别  

    复杂度, 将复杂性交给编译器。举一个例子,CISC提供的乘法指令,调用时可完成内存a和内存b中的两个数相乘,结果存入内存a ,需要多个CPU周期才可以完成;而RISC不提供“一站式”的乘法指令,需
    发表于 07-30 17:21

    递归神经网络的实现方法

    递归神经网络(Recursive Neural Network,简称RNN)是一种特殊类型的神经网络,其特点在于能够处理具有层次或树状结构的数据,并通过递归的方式对这些数据进行建模。与循环神经网络
    的头像 发表于 07-10 17:02 323次阅读

    递归神经网络结构形式主要分为

    递归神经网络(Recurrent Neural Networks,简称RNN)是一种具有时间序列处理能力的神经网络,其结构形式多样,可以根据不同的需求进行选择和设计。本文将介绍递归神经网络的几种主要
    的头像 发表于 07-05 09:32 525次阅读

    递归神经网络与循环神经网络一样吗

    神经网络是一种基于树结构的神经网络模型,它通过递归地将输入数据分解为更小的子问题来处理序列数据。RvNN的核心思想是将复杂的序列问题
    的头像 发表于 07-05 09:28 849次阅读

    递归神经网络是循环神经网络吗

    递归神经网络的概念 递归神经网络是一种具有短期记忆功能的神经网络,它能够处理序列数据,如时间序列、文本、语音等。与传统的前馈神经网络不同,递归神经网络的神经元之间存在循环连接,使得
    的头像 发表于 07-04 14:54 753次阅读

    递归神经网络的结构、特点、优缺点及适用场景

    识别、时间序列分析等领域有着广泛的应用。本文将详细介绍递归神经网络的结构、特点、优缺点以及适用场景。 一、递归神经网络的结构 基本结构 递归神经网络的基本结构包括输入层、隐藏层和输出层
    的头像 发表于 07-04 14:52 1351次阅读

    PCB与PCBA工艺复杂度的量化评估与应用初探!

    , 不知道如何区分普通和复杂的PCB和 PCBA的设计,并采用什么样的方式来处理。 基于上述考虑, 我们参考了业 界已有的作法, 设计了一个PCB 和 PCBA的工艺复杂度计算公式以解决这 方面
    发表于 06-14 11:15

    关于C语言中的递归

    递归指的是在函数的定义中使用函数自身的方法。
    发表于 02-26 10:34 389次阅读
    关于C语言中的<b class='flag-5'>递归</b>