面试经常遇到有人问菲波那切数列,并且问题也越来越刁钻,递归,非递归,尾递归等各种实现方式不一而足,已经不是最开始那个正经的斐波那契了。弄来弄去,还是要理解他的实现原理,以不变应万变。

数列形式:1,1,2,3,5,8,13·······求第n个数(n>=3)

这个数列的第n个数,等于前两个数的和,数列的前两个数为固定值,从第三个开始形成规律。现在说一下我对n的理解,很多网上的数列都是从0开始的,0,1,1,2,3······(n>=3),我觉着这个n的含义是第几个数,第0个数总感觉怪怪的,如果只是纯数学不管n的含义,那倒是随便。

正常递归:

public function test($n){if($n<=0) return false;if($n==1||$n==2) return 1;return test($n-1)+test($n-2);}

执行结果:n=35 结果:9227465 时间:16秒

尾递归:

 function lastTest($n,$res1,$res2){if($n==1) return $res1;return lastTest($n-1,$res2,$res1+$res2);}//调用
echo lastTest($n,1,1)

执行结果:结果:9227465 时间:0.0000472069秒

先解释一下这俩个递归和结果为什么差距这么大:

第一:正常递归那个一次递归调用两次本身,类似于二叉树往下分裂,1生2,2生4,对于内存的消耗是指数级增长。而尾递归每次只是调用一次本身,内存消耗是线性增长。

第二:随便举个例子,求第6个数,正常递归:test(5)+test(4) 继续分裂 test(4)+test(3)+test(3)+test(2) 继续分裂:test(3)+test(2)+test(2)+test(2)+test(2) 继续分裂 test(2)+test(2)+test(2)+test(2)+test(2)+test(2),可以看到,相同的值他要进行多次重复运算。尾递归:每次算完的res1+res2的值都会赋给下一次循环的的res2,然后将res2赋给res1,不会进行重复运算。

假如计算第6个数,res1每次计算等于上次的res2,res2每次计算等于上次的res1+res2:

尾递归执行演示
n res1 res2
6 1 1
5 1 2
4 2 3
3 3 5
2 5 8
1 8 13

我只计算到第35个数,是因为数再大正常递归已经超过php脚本默认执行时间30秒,再大很快内存就超了。这个算法要是运行在程序中简直就是毒瘤······

下边是非递归for循环(这两个for循环其实一样的就是一个递增一个递减):

正常循环:

function test($n){if($n<=0) return false;if($n==1||$n==2) return 1;$res1 = 1;$res2 = 1;for ($i=3; $i <=$n ; $i++) { $res = $res1+$res2;$res1 = $res2;$res2 = $res;}return $res;}

执行结果:结果:9227465 时间:0.0000119209秒

也是正常循环(代码就改了一点点):

function test($n){if($n<=0) return false;if($n==1||$n==2) return 1;$res1 = 1;$res2 = 1;for ($i=$n; $i >=3 ; $i--) { $res = $res1+$res2;$res1 = $res2;$res2 = $res;}return $res;}

执行结果:结果:9227465时间:0.0000119209秒

这俩个for循环的时间刚好一样,多点几次相差不大,我就用这两个时间了。尾递归那个很厉害了,竟然跟for循环一个量级,不过还是慢了4倍左右,多刷几次都是4倍左右,第一个就不说了。

所以这里边就牵扯到一个程序优化问题,面试的时候如果问你程序如何优化,我觉得尽量不用递归也算是很重要的一个优化手段。

菲波那切数列(递归非递归)相关推荐

  1. 阶乘 c语言 fushu,JS递归实现阶乘和菲波那切数列

    当我们需要使用递归来完成某些操作的时候,我们先要了解什么是递归 什么是递归? 递归,就是在运行的过程中调用自己. 一般来说,递归需要有边界条件.递归前进段和递归返回段. 当边界条件不满足时,递归前进: ...

  2. 008 -菲波那切数列

    对第n位菲波那切数列的值进行求解 菲波那切数列 (1)递归方法实现 //递归实现斐波那契数列public static int calculateOne(int num) {if(num==0)ret ...

  3. 求菲波那切数列数列第n项三种方法小结

    菲波那切数列数列的应用场景还是比较多的,比如可以在考试的时候考你递归啊,早上碰到的一道题就是这样,骄傲地写下递归方程,结果TLE了,然后旁边的大神给我说了一个叫滚动数组的东西...题目是这样的You ...

  4. 剑指offer(7)——C++实现菲波那切数列

    题目 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). 考察点 菲波那切数列: f(x)={0,n=01,n=1f(n−1)+f(n−2),n&g ...

  5. 剑指offer:菲波那切数列

    一.题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项.n<=39 解题思路: 菲波那切数列:指的是这样一个数列:1.1.2.3.5.8.13.21.34.- ...

  6. php菲波那切数列,php实现菲波那切数列和杨辉三角

    1.递归  显示斐波那契数列 function recursion($num){ //判断是否小于0 if($num<0){ return -1; } if($num==1){ return 0 ...

  7. 菲波那切数列案例演示(递归方法)

    /** * 功能:菲波那切数列案例演示(递归方法) * 详情:斐波那契数,亦称之为斐波那契数列(意大利语: * Successione di Fibonacci),又称黄金分割数列.费 * 波那西数列 ...

  8. 菲波那切数列几种实现

    菲波那切数列几种实现 递归 for循环 while循环 特征方程 个人一点愚见,有问题还望指出勿喷 特征方程是看过大佬们的结果才知道的,还特意去学习了被忘掉的特征方程. 递归 /*** 递归计算* 时 ...

  9. python函数-返回菲波那切数列for,range,append

    #返回菲波那切数列的列表 def fibs(num):     fibs=[0,1]     for i in range(num):         fibs.append(fibs[-2]+fib ...

最新文章

  1. easypoi实现Excel导入
  2. 分布式框架-日志系统思路及实现
  3. linux用户登录实验,Linux用户和组相关命令及实验
  4. mysql 检索操作时间段_postgresql数据库使用说明_实现时间范围查询
  5. 拓端tecdat|SARIMA,神经网络,RNN-LSTM,SARIMA和RNN组合方法预测COVID-19每日新增病例
  6. PyQT5 QtWidgets 设置单元格不可编辑/可编辑 恢复单元格默认设置
  7. python 颜色调整(饼状图)
  8. QA问答系统中的深度学习技术实现
  9. 一览数据异步加载的解决方案
  10. python图书销售系统
  11. 补天漏洞响应平台基本介绍
  12. 计算机联锁想系统包括哪几层,计算机联锁系统技术_习题.ppt
  13. C++之enum与switch
  14. 数据结构---散列表(哈希表)链地址法
  15. undo歌词中文音译_UNDO歌词及翻译
  16. chip在计算机英语什么意思,chip是什么意思中文翻译
  17. 局域网映射IPV6记录
  18. 百度一键Root使用教程
  19. 泳池马赛克让你徜徉在在海洋般的湛蓝与天际之间
  20. JWT如何解析过期的token中的信息

热门文章

  1. 恐龙跳一跳游戏python_【Python】Python代码制作”恐龙跳一跳”小游戏
  2. Android游戏开发–游戏循环
  3. 计算机课反思的作文600字,期中考试过后的反思作文600字(精选10篇)
  4. android vold,Android6.0 MountService和vold详解(三) vold SD卡、otg
  5. 《论文笔记》DOOR-SLAM:Distributed,Online, and Outlier Resilient SLAM for Robotic Teams
  6. MAGICIAN IS CASTOR (Castor JDO,Castor XML,魔术)
  7. Vue中父子组件的六种通信方式
  8. 怎么区分SSL证书的级别呢
  9. 借场雪吧~ js下雪动画 canvas画布实现下雪特效
  10. only batches of spatial targets supported (3D tensors) but got targets of dimension