浅谈递归和递归优化

334 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

 每天一小步,成功一大步。大家好,我是程序猿小白 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项斐波那契数列使用递归和递归优化,以及动态规划的一些浅见,如有错误,欢迎掘友们批评指正。