斐波那契数列

  斐波那契数列满足如下定义:

    当n=0时,f(0)=0;

    当n=1时,f(1)=1;

    当n>1时,f(n)=f(n-1)+f(n-2);

  可以很快写出类似如下的代码:

1 public static long f(int n){
2         if(n < 0) return -1;
3         if(n == 0) return 0;
4         if(n == 1) return 1;
5         return f(n - 1) + f(n - 2);
6     }

  但是如上递归解法有很严重的效率问题,例如计算f(10)的值,需要f(8)和f(9)的和,子递归一f(8)需要计算f(6)和f(7)的和,子递归二中计算f(9)的值需要f(8)和f(7)的和,此时f(8)又重复算了一次。此算法的时间复杂度是以n的指数的方式递增的。

  改进的方法可以考虑从f(0)逐步计算到f(n)(即先根据f(0)和f(1)算出f(2),再根据f(1)和f(2)算出f(3)……),并用一个长度为2的整型数组存储每次需要迭代的值。很明显,此算法的时间复杂度值有O(n)。

 1 public static long f(int n){
 2         if(n < 0) return -1;
 3         long[] arr = {0, 1};
 4         if(n < 2) return arr[n];
 5         long pSum;
 6         for(int i = 2; i <= n; i++){
 7             pSum = arr[0] + arr[1];
 8             arr[0] = arr[1];
 9             arr[1] = pSum;
10         }
11         return arr[1];
12     }

  接下来来看一下斐波那契数列的应用

  题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶,求该青蛙跳上一个n级台阶总共有多少种跳法?

  先从最简单情况出发:

    如果有1级台阶,则只有一种跳法,即f(1)=1。

    如果有2级台阶,则可以有两种跳法(1级1级跳或2级跳),即f(2)=2。

    如果有3级台阶,考虑第一次跳的时候有两种选择:一种是一次跳1级,则此跳法数目等于剩下(3-1)级台阶的跳法,即等于f(3-1),另一种是一次跳2级,则此跳法数目等于剩下的(3-2)级台阶的跳法,即等于f(3-2),所以f(3)=f(3-1)+f(3-2)=3。

  再从一般情况出发:

   当n>2时,第一次跳有两种选择:一种是一次跳1级,则跳法数目等于后面剩下(n-1)级台阶的跳法,即f(n-1),一种是一次跳2级,则跳法数目等于后面剩下的(n-2)级台阶的跳法,即f(n-2),所以f(n)=f(n-1)+f(n-2)。

  不难看出这实际上就是斐波那契数列了。

原文地址:https://www.cnblogs.com/honghuzidelaoren/p/3637911.html