前言

在这学期(大三上)去“蹭”了一次校招面试题,编程题中就有一道关于斐波那契数列的编程问题。如果不选择递归求解,就需要说明原因。当时还没怎么接触算法这方面的知识(笔者非科班),关于什么运行时间分析、空间复杂度分析的就是一脸懵逼,于是就描述了下可能会引发栈溢出的问题。在慢慢学习了一些算法基础之后,才明白那道题想考的就是关于运行时间的分析!


什么都别说,先“走”两步

下面是使用递归计算斐波那契数列第n项的例程:

long fib(int n) {if (n <= 1) {return 1;} else {return fib(n - 1) + fib(n - 2);}
}

下面开始计算运行时间:

  1. 设T(N)为函数fib(n)的运行时间,当n ≤ 1时,运行时间等于某个常数值,也就是执行if条件判断的时间,那么T(0) = T(1) = 1(时间单位);
  2. 当n ≥ 2时,T(N) = T(N - 1) + T(N - 2) + 2(2表示执行条件判断和加法的时间);
  3. 由fib(n) = fib(n - 1) + fib(n - 2), n ≥ 2,由归纳法可以证明T(N) ≥ fib(N),同理可证当n > 4时,fib(n) > (3 / 2) ^ n,也就是说(3 / 2) ^ n = o(T(N))勘误) ,即运行时间大于随着n的增加呈指数增长的情形,可见此场景下如此使用递归效率的低下。

附:

证明1:
基准情形:T(0) = T(1) = fib(0) = fib(1) = 1
归纳假设:当0 ≤ n ≤ N,T(N) ≥ fib(N)
则只需证明T(N + 1) ≥ fib(N + 1)即可。
而T(N + 1) = T(N) + T(N - 1) ,由归纳假设可得:
T(N + 1) ≥ fib(N) + fib(N - 1) => T(N + 1) ≥ fib(N) ,原命题得证。

证明2:
基准情形:fib(5) = 8 > ((3 / 2) ^ 5), fib(6) = 13 > ((3 / 2) ^ 6)
归纳假设:当4 ≤ n ≤ N时,fib(N) > ((3 / 2) ^ N)
则只需证明fib(N + 1) > ((3 / 2) ^ (N + 1)) 即可。
而fib(N + 1) = fib(N) + fib(N - 1) ,由归纳假设可得:
fib(N + 1) > (3 / 2) ^ N + (3 / 2) ^ (N - 1) => fib(N + 1) > (3 / 2) ^ (N + 1) ÷ (3 / 2) + (3 / 2) ^ (N + 1) ÷ (3 / 2) ^ 2 => fib(N + 1) > (3 / 2) ^ (N + 1) * (10 / 9) => fib(N + 1) > (3 / 2) ^ (N + 1)

在给出普通数组和for循环的实现,以作对比:

for (int i = 0; i < numbersCount; i ++) {if (i <= 1) {numbers[i] = 1;} else {numbers[i] = numbers[i -1] + numbers[i - 2];}
}

可以很容易得到运行时间T(N) = O(N),比起使用递归,运行时间被实质性的减少了。之所以这样递归的运行时间开销很大是因为做了很多重复的工作,也就是每求一个数都需要递归到基准情形,N越大,两次起始的递归交叠程度越大,效率自然而然就降低了!

总结

在学习算法的很短的日子了就深刻体会到了一点:学好数学很重要、学好数学很重要、学好数学很重要!特别是一些数学公式的记忆,比如让你求等差数列的前项和,如果记不得公式,恐怕你就只有循环求解了,但如果你记得的话就是一个公式就可以搞定的啊!当然,这只是一个简单的比喻,但本质的道理是相同的。所以如果你还有数学课,那么且行且珍惜

勘误

在这里敲打一遍几个记法的定义,给自己长长记性:

  • 如果存在正整数c和n0使得当N≥n0时T(N) ≤ cf(N),则记为T(N) = O(f(N))。
  • 如果存在正常数c和n0使得当N≥n0时T(N) ≥ cg(N),则记为T(N) = Ω(g(N))。
  • T(N) = ⊝(h(N))当且仅当T(N) = O(h(N))和T(N) = Ω(h(N))。
  • 如果对所有的常数c存在n0使得当N > n0时T(N) < cp(N),则记为T(N) = o(p(N))。

可见,此处下这样的定义是不恰当的。

斐波那契数列使用递归的运行时间分析相关推荐

  1. 斐波那契数列python递归 0、1、1、2、3_python: 递归和递推方法求斐波那契数列

    1.  斐波那契数列 序号 0 1 2 3 4 5 6... 数列 0 1 1 2 3 5 8... 2.  三种程序 import time time1 = time.clock() #斐波那契数列 ...

  2. (兔子繁殖问题)斐波那契数列:递归非递归解法

    题目 假设一对幼年兔子需要一个月长成成年兔子,一对成年兔子一个月后每个月都可以繁衍出一对新的幼年兔子.不考虑死亡的情况,问第 N 个月时共有多少对兔子? 这是一个典型的斐波那契数列问题,即 第一个月有 ...

  3. Python输出斐波那契数列【递归、迭代】

    Python输出斐波那契数列[递归.迭代] 首先 斐波那契数列的定义是什么? 斐波那契数列指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.--在数学上,斐波那契数列以如下被以递推的方 ...

  4. 斐波那契数列(递归+源码+注释)

    斐波那契数列(递归+源码+注释) 公元 1202 年,意大利数学家莱昂纳多·斐波那契提出了具备以下特征的数列: 前两个数的值分别为 0 .1 或者 1.1: 从第 3 个数字开始,它的值是前两个数字的 ...

  5. 递归与分治——斐波那契数列非递归,递归,与优化后的递归算法

    斐波那契数列: 1.1.2.3.5.8.13.21.-- 简单说,就是前两项的和是第三项的值. 1.求第N个斐波那契数的值(非递归) //斐波那契数列 int fun(int n) {int a = ...

  6. 斐波那契数列python递归 0、1、1、2、3_python实现斐波那契数列的多种方式

    正文共: 3269字 8图 预计阅读时间: 9分钟 每日分享 The great pleasure in life is doing what people say you cannot do. 人生 ...

  7. python用递归法写斐波那契_python实现斐波那契数列: 递归+备忘录法+动态规划实现...

    1.为什么备忘录法和动态规划法: 斐波那契是很多人入门递归思想的第一课,所以很多人都会最简单的一种递归写法,但是其实递归的过程,他的时间复杂度非常高,达到了O(2的n次方)这样的一个指数级别. 先看最 ...

  8. access求斐波拉契数列_打印目录,斐波那契数列的递归与循环,牧场牛数

    实验报告 1 任务概述(任务说明) 1 f(n)=f(n-1)+f(n-2) f(0)=f(1)=1 , 求斐波那契数列第 20 项, 分别用循环和递归的方式, 比较时间效率.提示:可以使用 c 函数 ...

  9. 斐波那契数列,递归与非递归c语言实现

    问题描述:求解斐波那契数列,分别采用递归方式与非递归方式  =2" class="mathcode" src="https://private.codecogs ...

最新文章

  1. java 线程 thread.join_java线程Thread的join方法。
  2. oracle视图(转)
  3. Linux查看网卡状态
  4. Lesson3 Shader着色器
  5. POJ - 1358 Housing Complexes(二分图最大匹配)
  6. 散列表查找失败平均查找长度_Python数据结构与算法56:排序与查找:冲突解决方案...
  7. java formatter()_Java Formatter locale()用法及代码示例
  8. Centos7安装Redis4.0.8
  9. 大众点评被合并至美团? 官方回应:不存在这种可能性
  10. 【经验心得】每刷新一次页面就顺序更换一张图片的js特效
  11. Linux下vsftp服务器原理、安装、配置实战
  12. 数据结构(C语言版第二版)思维导图
  13. 【自动驾驶轨迹规划之RRT算法】
  14. 基础练习 特殊回文数 C语言
  15. Git Extension 合并分支
  16. 如何快速爬取网页数据(干货)
  17. 叶俊获“约翰·格雷博士中国行”最佳贡献奖
  18. 新手都能用到的140个电脑技巧
  19. 梁漱溟:人生的三种态度 | 合道的生活
  20. Flash鼠绘教程:临摹徐悲鸿的骏马图

热门文章

  1. [Java 8 HashMap 详解系列]7.HashMap 中的红黑树原理
  2. 【正点原子FPGA连载】第二十五章HDMI方块移动实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1
  3. wordpress插件_7个WordPress插件为您的网站准备圣诞节
  4. 自助式卡拉 OK 娱乐超市审批条件
  5. 罗技键鼠套装MK295和K270差了将近100元,区别是什么
  6. 卢松松:互联网企业玩手机
  7. 〖Python零基础入门篇㊸〗- 异常处理的避坑指南
  8. 硬件-Array配置负载均衡
  9. 国有企业利润突破9000亿的喜与忧
  10. Google Maps API V3学习--- 简单地图显示