遞歸求解斐波那契數列的問題

費波那契數列意大利語:Successione di Fibonacci),又譯費波拿契數斐波那契數列費氏數列黃金分割數列php

數學上,費波那契數列是以遞歸的方法來定義:java

  • F_0=0
  • F_1=1
  • F_n = F_{n-1}+ F_{n-2}(n≧2)

用文字來講,就是費波那契數列由0和1開始,以後的費波那契係數就由以前的兩數相加。首幾個費波那契係數是(OEIS A000045):算法

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,………………緩存

特別指出0不是第一項,而是第零項。數據結構

(以上來自維基百科)函數

求解Fibonacci數列用java的遞歸很簡單:遞歸

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

但用遞歸求解的效率幾乎是沒法容忍的,當n爲50是,估計須要好幾分鐘,由於每遞歸調用一次fibonacci()函數,都會從新計算fibonacci(n - 1)和fibonacci(n - 2),這樣有不少數都是重複計算的,一個比較簡單的方法就是用一個數據結構將計算後的值緩存起來,ci

求解時先從緩存裏面拿數據,沒有的話再計算並將計算後的結果加到緩存裏面,這樣就避免了不少重複計算。下面是用HashMap將數據緩存的例子:get

private static HashMap<Integer, Long> hashMap = new HashMap<Integer, Long>();

private static long value;

 

public static long effectFibonacci(int n)
    {
        if(n == 0 || n == 1)
        {
            return 1;
        }
        if(hashMap.containsKey(n))
        {
            return hashMap.get(n);
        }
        else
        {
            value = effectFibonacci(n - 1) + effectFibonacci(n - 2);
            hashMap.put(n, value);
        }
        return value;
    }

這個算法跟上一個的效率相比有了很大的提升,當n = 1500時,花費的時間大約是 3082077 microseconds,而用上一個遞歸直接算,不知何年才能得出結果。

 

還有一種求解Fibonacci問題的方法就是利用動態規劃算法,動態規劃算法是將一個較大的問題分解爲若干類似子問題,求解子問題而後合併並獲得原問題的解,動態規劃算法適用於有重疊子問題和最優子結構性質的問題,重疊子問題即原問題可分解爲若干的求解算法類似的子問題,最優子結構就是局部最優致使全局最優,即可以將子問題的解合併後獲得原問題的解,這跟貪心算法類似。下面是用動態規劃算法求解Fibonacci數列問題:

public static long bestFinabocci(int n)
    {
        long previous = 1, next = 1;
        long tmp = 2;
        for (int i = 2; i <= n; i++)
        {
            tmp = previous + next;  //從2開始,每個後面的數都是前面兩個數之和
            previous = next;
            next = tmp;
        }
        return tmp;
    }

跟上一個使用遞歸緩存求解,動態規劃算法在效率上有了很大的提升,一樣當 n = 1500是,遞歸緩存花費的時間大約是 3082077 microseconds,而動態規劃花費的時間大約是 40410 microseconds。

由上面的實驗來看,在遞歸的問題上,最好使用循環代替遞歸,不得不用到遞歸時,最好將數據緩存起來避免重複計算,不要直接調用遞歸函數。

相關文章
相關標籤/搜索