Php斐波那契数列尾递归优化,斐波那契数列的各种优化:尾递归(递归不爆栈),记忆化搜索,动态规划...

目录

1.普通的递归斐波那契数列

2.尾递归:在使用递归的情况下,不爆栈

3.记忆化搜索:减少不必要的重复计算,自上而下

4.动态规划:自上而下,非递归

1.普通的递归斐波那契数列

function fac($n){

if($n == 1 || $n == 2) return 1;

else return fac($n-2) + fac($n-1)

}

2.尾递归:在使用递归的情况下,不爆栈

普通的递归,运行栈会被函数的递归调用占满了

因此在要求使用递归的情况下,可以使用尾递归

每次调用函数时不生成新的运行栈,利用上一次的结果

/**

* $a充当收集器,收集上一次运行栈的返回值,之后栈空间会被回收

* $a和$b参与每次的计算

* $n是斐波那契数列执行的次数

*/

function fac1($a,$b,$n){

if($n>2) return fac1($a+$b,$a,$n-1);

return $a;

}

3.记忆化搜索:减少不必要的重复计算,自上而下

在原本的斐波那契递归中,总会像如下图一样递归到最后再返回结果

其中,例如 以5为例,3 往下的部分,就会被重复计算两次,2往下的部分会被重复计算3次

如果数据量大的情况下,记忆化搜索减少的计算量是十分可观的

1161a8864a375eb755f6ee79c77c4859.png

用该方法可以大大优化斐波那契数列解决速度

class Solution{

private $memory = []; //记录当前数字是否已经求出解

public function fac($n){

if($n == 0) return 0;

if($n == 1) return 1;

if(empty($this->memory[$n])) //若没有对应的解,则继续进行递归

$this->memory[$n] = $this->fac($n-1) + $this->fac($n-2);

return $this->memory[$n]; //有解则直接返回该斐波那契数列

}

}

$q = new Solution();

echo $q->fac(40);

4.动态规划:自上而下,非递归

非递归,减少了系统栈的建立,比记忆化搜索还快

将原问题拆解成若干子问题,同时保存子问题的答案,使得每个子问题只求解一次,最终获得原问题的答案

function fac($n){

if($n == 1 || $n == 2) return 1;

$a = 1;

$b = 1;

$res = 0;

for($i = 3;$i<=$n;++$i){

$res = $a + $b;

$a = $b;

$b = $res;

}

return $res;

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值