例子1:  斐波那契数列的定义如下:F1 = 1, F2 = 1, Fn =Fn–1 + Fn–2 (n ≥ 3)。如果用递归算法计算斐波那契数列的第 n 项,则其时间复杂度为O(Fn)

O(Fn)为指数形式。具体可以从Fn的通项公式中看出:

递归的代码如下:

def fibonacci(n):if n == 1:return 0if n == 2:return 1return fibonacci(n - 1) + fibonacci(n - 2)

这里值得说明的是这种递归方式之所以复杂度达到了指数级别,是因为算法实现过程存在重复计算过程,以f(6)为例,递归树结构如下:

可以看到递归计算第6项时,需要重复计算两次f(4),三次f(3),以二叉树的结构向下延伸,如测试的例子所示,当计算到第40项时,会有36项都需要重复计算,且越往下,重复次数越多,效率也很低下。

那么算法怎么改进呢?

思路一:通过尾递归实现

def lastFibonacci(n, ret1, ret2):if(n == 1):return ret1return lastFibonacci(n - 1, ret2, ret1 + ret2)

尾递归快就快在它不需要重复计算某一项,利用了一种技巧就是每次递归调用时,它会把之前已经计算好的结果以参数的形式传递过去,同样以f(6)为例:

n ret1 ret2
6 0 1
5 1 1
4 1 2
3 2 3
2 3 5
1 5 8

思路二:动态规划的思想:迭代实现

def fibonacci(n):a = 0b = 1result = 0;if n == 1:return 0if n == 2:return 1for i in range(3, n+1):result = a +ba = bb = resultreturn result

补充说明:尾递归是什么?

还是举例子说明吧

以求阶乘为例:

非尾递归版本

def fact(n):if n < 0:return 0elif n == 0 || n == 1:return 1elsereturn n * fact(n - 1)

尾递归版本

def facttail(n, res):if n < 0:return 0elif n == 0:return 1elif n == 1:return reselse:return facttail(n - 1, n*res)

代码1:在每次函数调用计算n倍的(n-1)!的值,让n=n-1并持续这个过程直到n=1为止。这种定义不是尾递归的,因为每次函数调用的返回值都依赖于用n乘以下一次函数调用的返回值,因此每次调用产生的栈帧将不得不保存在栈上直到下一个子调用的返回值确定。

代码2:函数比代码1多个参数res,除此之外并没有太大区别。res(初始化为1)维护递归层次的深度。这就让我们避免了每次还需要将返回值再乘以n。然而,在每次递归调用中,令res=n*res并且n=n-1。继续递归调用,直到n=1,这满足结束条件,此时直接返回res即可。

可以仔细看看两个函数的具体实现,看看递归和尾递归的不同!

示例中的函数是尾递归的,因为对facttail的单次递归调用是函数返回前最后执行的一条语句。换句话说,在递归调用之后还可以有其他的语句执行,只是它们只能在递归调用没有执行时才可以执行。

尾递归是极其重要的,不用尾递归,函数的堆栈耗用难以估量,需要保存很多中间函数的堆栈。比如sum(n) = f(n) = f(n-1) + value(n) ;会保存n个函数调用堆栈,而使用尾递归f(n, sum) = f(n-1, sum+value(n)); 这样则只保留后一个函数堆栈即可,之前的可优化删去。

例子2: 设某算法的计算时间表示为递推关系式T(n)= T(n -1) + n(n 为正整数)及T(0) = 1,则该算法的时间复杂度为O(n^2)

T(n)=T(n-1)+n                             (1)

T(n-1)=T(n-2)+n-1                       (2)

T(n-2)=T(n-3)+n-2                       (3)

T(n-3)=T(n-4)+n-3                       (4)

……

T(3)=T(2)+3                                 (n-2)

T(2)=T(1)+2                                 (n-1)

T(1)=T(0)+1                                 (n)

将(n)式带回(n-1) 式,将(n-1)式带回(n-2) 式,将式子依次带回,最后带回(4) 式,(3) 式,(2) 式,(1) 式。带入式子结果如下:

T(n)=T(0)+1+2+3+……+n-3+n-2+n-1+n

计算结果如下:

T(n)=1+1+2+3+……+n-3+n-2+n-1+n

T(n)=1+(1+n)*n/2

例子3:假设某算法的计算时间可用递推关系式T(n)=2T(n/2)+n表示,则该算法的时间复杂度为O(nlog2(n))
T(n)=2T(n/2),所以T(n)/n=T(n/2)/(n/2)+1,
T(n/2)/(n/2)=T(n/4)/(n/4)+1;
T(n/4)/(n/4)=T(n/8)/(n/8)+1;

...
T(2)/2=T(1)/1+1;
这些等式左右相加,T(n)/n=T(1)+1*log2(n);
即T(n)=nT(1)+n*long2(n);
复杂度为O(nlog2(n))

递推公式求时间复杂度相关推荐

  1. 使用主定理求时间复杂度

    文章目录 使用主定理求时间复杂度 主定理 直接可用主定理 转化之后可以利用主定理 使用主定理求时间复杂度 很多算法最后都可以写出 T(n)=aT(nb)+f(n))(a≥1,b≥1)T(n)=aT(\ ...

  2. 【O(n)时间复杂度】递推公式的时间复杂度T(n)=T(n-1)+n

    目录 设某算法的递推公式是T(n)=T(n-1)+n,T(0)=1,则求该算法中第n项的时间复杂度为() T(n)=T(n-1)+O(1)的时间复杂度: 设某算法的递推公式是T(n)=T(n-1)+n ...

  3. hdu1799(用递推公式求组合的个数)

    题目意思: 我们知道,在编程中,我们时常需要考虑到时间复杂度,特别是对于循环的部分.例如, 如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次OP运算,如果代码中出现 f ...

  4. UVALive 7040 Color (容斥原理 + 组合数学递推公式 + 求逆元 + 基础数论)

    传送门 英文题目: Recently, Mr. Big recieved n owers from his fans. He wants to recolor those owers with m c ...

  5. 递归式求时间复杂度的递归树的方法举例说明

    用递归树的时候注意一下递归树的写法规则: (1) 每层的节点为T(n) = kT(n / m) + f(n)中的f(n)在当前的n/m下的值,所以每一层并不是写为T(n / m) , 并且递归树的根节 ...

  6. 递归式求时间复杂度的代入法与迭代法的举例讲解

    在算法分析中,当一个算法中包含递归调用时,其时间复杂度的分析会转化为一个递归方程求解.实际上,这个问题是数学上求解渐近阶的问题,而递归方程的形式多种多样,其求解方法也是不一而足,比较常用的有以下四种方 ...

  7. java求时间复杂度求值_计算时间复杂度例题(示例代码)

    一.引言: 写给自己看 算法是程序的灵魂,想学好算法就必须先搞懂时间复杂度 算时间复杂度就是算基本语句条数 5个例题 二.例题 1). for(int i=0; i for(int j=i; j Sy ...

  8. 每日一题/001/微积分/递推公式求定积分

    题目(2021年中科大考验数学分析考试): 求定积分: ∫0πsin⁡(2n+1)xsin⁡(x)\int_0^\pi\frac{\sin(2n+1)x}{\sin(x)}∫0π​sin(x)sin( ...

  9. 如何用递归树求快速排序时间复杂度

    其实也就是点看算法导论的心得,感觉算法导论写的有点不详细的补充 快速排序 我的理解就是利用分治法 ,递归排序最后合并的排序,因为快速排序的最坏时间复杂度比较低所以快速被叫做快速排序如图 对于求快速排序 ...

最新文章

  1. 28岁女博士生被骂“学术媛”,只因在网上分享自己牛津年级第一成绩毕业......
  2. IOS 设置视图半透明子控件不透明
  3. java注销登录_java实现注销登录
  4. 数据库元数据数据字典查询_8_列出给定表的默认约束
  5. linux沙箱隔离_Linux沙箱技术介绍
  6. 一步步编写操作系统 19 改进MBR,直接操作显卡
  7. 一次查找sqlserver死锁的经历
  8. NOI数据结构:后缀树
  9. Earth’s best1段有机南瓜泥
  10. web前端时间戳转时间类型显示
  11. python入门教程第三讲_第三讲 使用Template
  12. Keil综合(01)一些常见文件类型的作用和功能说明
  13. Qt学习之路(37): Qt容器类之关联存储容器
  14. 计算机课评课用语,【数学评课50条】_评课常用语50条
  15. 修改表格字体颜色_为什么用格式刷无法匹配文字的字体和颜色?到底哪些特性可以匹配?...
  16. 哪些大学有计算机动漫专业,计算机专业考研有哪些值得推荐的院校?
  17. asp远程访问sql server数据库
  18. 日常折腾日记:手动配置UG二次开发环境——使用NX Open C++和Visual Studio
  19. OC Foundation框架 集合
  20. 对比分析冯诺依曼结构和哈佛结构。

热门文章

  1. 半正定松弛法(SDR)2021-11-06
  2. 心理咨询APP开发结合互联网的系统化管理,更好地满足用户需求
  3. Multidex记录二:缺陷解决
  4. Smart Cities是什么?未来城市技术的一些观点
  5. fastboot刷机小脚本
  6. 财报解读:Q2业绩指引未达预期,狂奔的爱彼迎要减速了?
  7. 不宜妄自菲薄,引喻失义
  8. mysql链接远程报错10061
  9. PAT Basic Level 1032 挖掘机技术哪家强(C++实现)
  10. Mac下安装tree