1. 程式人生 > >斐波那契數列的相關問題

斐波那契數列的相關問題

第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階即為兩者之和。恰好滿足斐波那契數列。

現在青蛙升級了每次可以跳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){return 1;}
        else {
            for(int i=1;i<=n;i++)
                sum+=jumpplus(n-1);
        }
        return sum;
    }