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

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

3天内不再提示

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

算法与数据结构 来源:代码随想录 作者:代码随想录 2022-07-13 11:33 次阅读

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

相信很多同学对递归算法的时间复杂度都很模糊,那么这篇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;
    }
    return result;
}

时间复杂度为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);
}

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

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

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

原文标题:关于递归算法的时间复杂度,你还不够了解

文章出处:【微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

审核编辑:彭静

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

    关注

    30

    文章

    4554

    浏览量

    66730
  • 二叉树
    +关注

    关注

    0

    文章

    74

    浏览量

    12238

原文标题:关于递归算法的时间复杂度,你还不够了解

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    时间复杂度为O (nlogn)的排序算法简述

    归并排序遵循分治的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后合并这些子问题的解来建立原问题的解。
    的头像 发表于 12-05 09:57 286次阅读
    <b class='flag-5'>时间</b><b class='flag-5'>复杂度</b>为O (nlogn)的排序<b class='flag-5'>算法</b>简述

    降低Transformer复杂度O(N^2)的方法汇总

    首先来详细说明为什么Transformer的计算复杂度是 。将Transformer中标准的Attention称为Softmax Attention。令 为长度为 的序列, 其维度为 , 。 可看作Softmax Attention的输入。
    的头像 发表于 12-04 15:31 478次阅读
    降低Transformer<b class='flag-5'>复杂度</b>O(N^2)的方法汇总

    FlashText算法的优势

    FlashText 算法是由 Vikash Singh 于2017年发表的大规模关键词替换算法,这个算法时间复杂度仅由文本长度(N)决定,
    的头像 发表于 11-01 09:44 192次阅读
    FlashText<b class='flag-5'>算法</b>的优势

    如何计算时间复杂度

    1 算法时间复杂度 算法(Algorithm)是求解一个问题需要遵循的,被清楚指定的简单指令的集合。 算法一旦确定,那么下一步就要确定该
    的头像 发表于 10-13 11:19 1034次阅读
    如何计算<b class='flag-5'>时间</b><b class='flag-5'>复杂度</b>

    RFID技术和防冲撞算法分析

    论文详细介绍了 RFID 技术, 并针对 RFID 技术中不可避免的碰撞问题进行分析。提出一种动态调整二进制搜索树防冲撞算法, 可以有效解决 RFID 标签冲突问题。在时间复杂度和空间复杂度
    发表于 09-22 06:04

    kicad的cpu架构移植复杂度评估

    工作的复杂度和工作量,即使他已经经过移植。作为我的数据集的一部分,我收集了kicad项目。我希望收集社会人士的意见,以支持我的评估。我很感谢你的帮助和回应!基于扫描工具,移植的复杂性被确定为困难,项目
    发表于 09-11 17:06

    kicad的架构移植复杂度评估

    各位网友大家好啊~~~~我正在实施一个工具,以评估CPU架构移植的复杂性。它主要关注RISC-V体系结构的移植。作为我的数据集的一部分,我收集了kicad项目。我希望收集社会人士的意见,以支持我
    发表于 09-11 17:03

    算法时间复杂度#数据结构

    数据
    未来加油dz
    发布于 :2023年07月18日 17:22:47

    算法时间复杂度2(2)#数据结构

    数据结构
    未来加油dz
    发布于 :2023年07月18日 16:40:10

    算法时间复杂度1(2)#数据结构

    数据结构
    未来加油dz
    发布于 :2023年07月18日 16:39:24

    算法时间复杂度1(1)#数据结构

    数据结构
    未来加油dz
    发布于 :2023年07月18日 16:38:44

    常见排序算法分类

    本文将通过动态演示+代码的形式系统地总结十大经典排序算法。 排序算法 算法分类 —— 十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序,由于其
    的头像 发表于 06-22 14:49 624次阅读
    常见排序<b class='flag-5'>算法</b>分类

    KMP算法详解

    KMP 算法主要用于字符串匹配的,他的时间复杂度 O(m+n) 。
    的头像 发表于 06-07 16:23 402次阅读
    KMP<b class='flag-5'>算法</b>详解

    排序算法之“归并算法”介绍

    ,分治思想一般就是使用递归来实现的。但是需要注意的是:递归是代码实现的方式,分治属于理论。接下来看一副图理解下: 说完它的思想:我们再来分析下时间复杂度。归并
    的头像 发表于 05-22 10:03 427次阅读
    排序<b class='flag-5'>算法</b>之“归并<b class='flag-5'>算法</b>”介绍

    SPFA 算法:实现原理及其应用

    源点的距离加上u到v的边的权重小于v的距离,则更新v的距离,并将v加入队列中。如果v已经在队列中,则不需要再次添加。 如果队列为空,则算法结束。如果队列非空,则回到步骤2。 SPFA算法时间
    发表于 04-29 12:43