斐波那契数列的相关问题

第0项为0,第1项为1,第2项为1,第3项为2…后面的项是之前两项的和。
这种后面的内容恰好需要前面的值得让人一下就想到了递归。

public static int fibonacci(int n) {  
        if(n == 0){
            return 0;
        }else if(n == 1||n==2){
            return 1;
        }else return (fibonacci(n-1)+fibonacci(n-2));
  }

再暴力一点!

public static int fibonacci(int n) {  
   (n<2)?  return n  : return (fibonacci(n-1)+fibonacci(n-2));
  }

看似简便但是对于fibonacci(n-1)和fibonacci(n-2)来说每个都要单独递归一遍实在很麻烦。而且数字一大还会产生栈溢出的现象。解决的办法就是用空间换时间改成用数组去记忆之前所运算的值:

public static int fibonacci1(int n){
      int[] arr = new int[n+1];
      arr[0] = 0;arr[1]=1;
      for(int i = 2;i<=n+1;i++){
          arr[i]=arr[i-1]+arr[i-2];
      }
      return arr[n+1];
}

其实用迭代的思路也能实现记忆功能(动态规划)//其实只需要两个变量我这里写麻烦了

public static int fibonacci2(int n){
       if(n<=1){return n;}
        int fibonacci1 = 0,feibonacci2=1,feibonacci3 =0;
        for(int i = 2;i<=n;i++){
            feibonacci3 = fibonacci1 + feibonacci2;
            fibonacci1 = feibonacci2;
            feibonacci2 = feibonacci3;
        }
        return feibonacci3;
    }

但是数据一大这就出现了毛病,我无法求第50项的值。换成long?可是再超过范围了又该怎么办??
这里就需要用到大数计算

 public static BigInteger fibonacci3(int n) {
        if(n == 0){
            return BigInteger.valueOf(0);
        }else if(n==1 ){
            return BigInteger.valueOf(1);
        }else return fibonacci3(n-1).add(fibonacci3(n-2));
    }

BigInteger a = new BigInteger(“1”);//构造a.add(b)//相加subtract();// 相减multiply(); //相乘divide(); //相除取整remainder();// 取余

在这里插入图片描述
这是斐波那契第50项的值,下面一行是所用时间,10分多钟吧。不得不说是真的卡。。。但是总算是算出来了。
好吧50项都十分钟了那51项还不得20多分钟???所以就需要用到矩阵的思想去解决。
奈何我数学不好,以后有机会再填这个坑。

斐波那契的思想还可以解决变态上楼梯的问题。一只青蛙每次可以上一阶或者两阶台阶。有n阶台阶请问有多少种方法?
不用递归的思想解决如下所示
在这里插入图片描述

 public static int jump(int n) {
        //首先求出最多有多少次跳偶数阶台阶
        int evenMix = n / 2;
        //下来思考在一堆1里面插入0个2乃至n/2个分别有多少种办法最后求和
        int sum = 0;
        for (int i = 0; i <= evenMix; i++) {//i  本次2阶的个数,

            int count = n - i;//跳本次总jump数
            sum  = sum + factorial(count)/factorial(count-i)/factorial(i);
                   }return sum;
    }
    
 public static int factorial(int n) {
            int sum = 1;
            while (n > 0) {
                sum = sum * n--;
            }
            return sum;
        }

运用递归
求n阶有多少种可能,最后一步无非就只可能跳1阶或者2阶,最后跳1阶的可能即n-1阶台阶的所有可能,最后跳2阶的可能即跳n-2阶台阶的所有可能。故n阶即为两者之和。恰好满足斐波那契数列。
该问题等价于有2n大小的矩形,用21大小的矩形去填请问共有多少种填法。

斐波那契还是原来的斐波那契,青蛙却已经不是原来的青蛙了。
现在青蛙升级了每次可以跳1~n个台阶,请问n个台阶共有多少种方法。
还是通过最后一步分析,最后一步可以1~n阶
最后1阶时 方法等于n-1阶
最后2阶时 方法等于n-2阶

最后n阶时 方法等于n-n阶//跳0阶时次数为1
代码如下:

public  static int jumpplus(int n){
        int sum = 0;
        if(n<2){return1;}
        else {
            for(int i=1;i<=n;i++)
                sum+=jump(n-1);
        }
        return sum;
    }

其实这样写还是麻烦了很多,更好的做法是先通过逻辑进行优化
jump(n)=jump(n-1)+jump(n-2)+…+jump(0);
jump(n-1)=jump(n-2)+jump(n-3)…+jump(0);
故jump(n)=2*jump(n-1);

猜你喜欢

转载自blog.csdn.net/qq_43313769/article/details/83352764
今日推荐