斐波那契数列指的是这样一个数列:0、1、1、2、3、5、8、13、21、34
代码解释:
<?php
/**
* @param $n
* @return int
* 1.
* 斐波那契数列
* 每次都要计算,所以每个f(n)都可能被计算两次,大量重复计算
* 时间复杂度 : O(2^n) 2的n次方,指数级别,爆炸 慢
* 把 f(n) 想做一个状态 n,这个状态n是由状态n - 1和状态n - 2相加转移而来,这就叫状态转移方程
*/
function fib1($n){
if($n == 1 || $n == 2) return 1;
return fib1($n-1) + fib1($n-2);
}
/**
* @param $arr
* @param $n
* @return int|mixed
* 2.
* 斐波那契数列( 在1的基础上优化 )
* 因为我们放了一个数组(备忘录),减少了冗余数据,把已经计算过的数据放入数组中,不必再去计算
* 时间复杂度: O(n)
*/
function fib(&$arr,$n){
if($n == 1 || $n == 2) return 1;
if(isset($arr[$n])) return $arr[$n];
$arr[$n] = fib($arr,$n-1) + fib($arr,$n-2);
return $arr[$n];
}
/**
* 3.
* 斐波那契数列( 跟2的效率基本相同 )
* 数组迭代解法
* 这个解法就是上面放一个数组的解法,不同的是上面的是从上往下面推算得出的结果
* 这个是数组从下往上面推算出来的结果 上面解法反过来就是现在这个解法
* 效率和上面备忘录基本相同
*/
function fib_Arr($n) {
if($n<1) return 0;
if($n == 1 || $n == 2) return 1;
$arr[1] = $arr[2] = 1;
for ($i=3; $i<=$n; $i++) {
$arr[$i] = $arr[$i-1] + $arr[$i-2];
}
return $arr[$i-1];
}
/**
* @param $n
* @return int
* 4.
* 斐波那契数列( 最后优化之后 )
* 其实当前值和之前的前两个值有关系,所以不需要建立特别长的数组然后再相加,只要存储当前值的前两个值就可以了
* 空间复杂度为: O(1)
* 这个技巧就是所谓的状态压缩
*/
function fib_Arr_1($n) {
if($n<1) return 0;
if($n == 1 || $n == 2) return 1;
static $prev = 1;
static $curr = 1;
for ($i=3; $i<=$n; $i++) {
$sum = $prev + $curr;
$prev = $curr;
$curr = $sum;
}
return $curr;
}