这是一个常见的算法题,在面试中经常碰到:
一栋楼有n阶楼梯,你只可以一次走一阶,或者一次走两阶,问走完n阶总共有多少种不同的走法?
首先我们假设n阶的走法总共有f(n)f(n)f(n)种走法,那么对应的,第n-1阶为f(n−1)f(n-1)f(n−1)种走法,第n-2阶为f(n−2)f(n-2)f(n−2)种走法,那么以上3个值有没有什么关系呢?
我们首先看下第n-1阶的,既然走到第n-1阶为f(n−1)f(n-1)f(n−1)种走法,那么他到第n阶只剩1个楼梯了,他只能走1步,所以用包含走到n-1阶的走法走到n阶的走法也是f(n−1)f(n-1)f(n−1)种。
然后我们再看下第n-2阶,从n-2阶走到n阶一共有2阶,这2阶有2种走法:
- 一次走完两阶
- 分两次走一阶的
其中第二种走法在走第一个一阶的时候会走到n-1阶,其实他已经属于f(n−1)f(n-1)f(n−1)的一种了,剩下一个一次走两步的,也会走到第n阶,那么我们就可以清晰的知道他们的关系了:
f(n)f(n)f(n) = f(n−1)f(n-1)f(n−1) + f(n−2)f(n-2)f(n−2)
这个公式是不是有点眼熟呢?不就是斐波那契数列么!
那么这道题我们就可以按照按解斐波那契数列来解了。
递归法:
function feib($n){
if($n==1)
return 1;
elif($n==2)
return 2;
else{
$re = feib($n-1) + feib($n-2);
}
return $re;
}
动态规划法:
function feib($n){
if($n==1)
return 1;
elif($n==2)
return 2;
else{
$feibList = [1,2];
for($i=2;$i<=$n;$i++){
$feibList[$i] = $feibList[$i-1] + $feibList[$i-2];
}
}
return $feibList[$n];
}