小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言
每天一小步,成功一大步。大家好,我是程序猿小白 gw_GW,很高兴能和大家一起学习每天小知识。
以下内容部分来自于网络,如有侵权,请联系我删除,本文仅用于学习交流,不用作任何商业用途。
摘要
本文通过斐波那契数列来使读者感受到递归优化的快乐。
求斐波那契数列
斐波那契数列简述
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
来源百度百科
基于求第n项斐波那契数列,这里给出三种解法给大家参考:
1. 递归
long long fib( int n ){
if(n == 2) return 1;
if(n == 1) return 0;
return fib(n-1) + fib(n-2);
}
直接使用递归非常简单,但是当n变得很大时,需要的时间很长很长了。不妨先搞个20来试一下。
2. 递归优化
long long fib( int n, long long result[], int len ){
if(n == 2) return 1;
if(n == 1) return 0;
if(len > n && result[n] != 0)
return result[n];
if(len > n)
result[n] = fib(n-1,result,len) + fib(n-2,result,len);
return fib(n-1,result,len) + fib(n-2,result,len);
}
递归过程中,会反复的调用已经递归过的递归式,这时我们就可以把该值保存在数组中,如果递归的时候碰到了该值,那就不再需要往下递归,直接返回即可。这样就节省了大量的时间。
3. 动态规划
long long fibn(int n){
long long dp[n+1];
dp[1] = 0;
dp[2] = 1;
for(int i=3;i<=n;i++)
dp[i] = dp[i-1] + dp[i-2];
return dp[n];
}
使用动态规划也可以节省大量时间,其实原理和上面差不多,使用数组把前一个值保留下来,就不必再花时间计算了。
需要注意的的,当n很大时可能会超过long long的范围(比如n=100),这时,就需要使用其他办法来保存数值。
结语
以上就是我基于求第n项斐波那契数列使用递归和递归优化,以及动态规划的一些浅见,如有错误,欢迎掘友们批评指正。