题目:写一个函数,输入n,求斐波那契数列的第n项;
解法一:
刚进大一的时候,学习c语言,斐波那契数列是经常用于展示递归的经典例子.但是从时间复杂度角度来说的话,采用尾递归这并不是一个优秀的算法.
public void Fibonacci(int n){
if(n<=0){
return 0;
}
if(n==1){
return 1;
}
return Finonacci(n-1)+Fibonacii(n-2);
}
从两个角度考虑
1. 首先递归调用涉及到一个效率的问题,因为在递归中总会涉及到一些重复的计算,时间复杂度太大,是n的指数关系;
2. 递归会占用资源,每次递归,内存中寄存器都会记录一些参数值以及地址值,如果递归深度大于内存中栈的深度,就会发生栈溢出(OutOfStackError);
时间复杂度的证明:
从上述代码容易推出一个递归等式:f(n)=f(n-1)+f(n-2)
其中f(0)=0,f(1)=1
这样就转换成求解二阶差分方程;
特征方程: λ^2-λ-1=0;
可以解的通解为:c1[(1+√5)/2]^n+c2[(1-√5)/2]^n;
时间复杂度:O([(1+√5)/2]^n)
;
为指数关系,时间复杂度高的吓人.. - - !
解法二:
public void Fibonacci(int n){
int[]array={0,1};
if(n<=1){
return array[n];
}
int min=0;
int max=1;
int result=0;
for(int i=2;i<=n;i++){
result=min+max;
min=max;
max=result;
}
return result;
}
没什么好解释的, 将时间复杂度由O([(1+√5)/2]^n)
降低为O(N)
;
解法三:
听说涉及到一个很偏僻的数学公式,可以吧时间复杂度降低到O(longN)
;
公式实在难以推导,数学渣渣我,感觉压力很大….
由Fibonacii衍生而来的几种算法题:
1. 青蛙跳台阶问题:
一只青蛙一次可以跳上1级台阶,也可以跳上2级,求该青蛙跳上一个n级台阶一共有多少种跳法?
思路:数学归纳法,推导出递归公式 f(n)=f(n-1)+f(n-2);即Fibonacii
数列出去第一项;
2. 变态青蛙跳台阶问题:
一只青蛙一次可以跳上1级台阶,也可以跳上2级,也可以跳上3级……也可以跳上n级,求该青蛙跳上一个n级台阶一共有多少种跳法?
思路:同理.数学归纳法归纳出递推公式:f(n)=2^(n-1)
3. 重叠格子问题:可以用2*1的小格子横着或者是竖着去覆盖更大的格子.请问.n个2*1的小格子有多少种方法去覆盖一个2*n的格子?
思路:仍然同理,数学归纳法,推导出递归公式 f(n)=f(n-1)+f(n-2);