LeetCode.509——斐波那契數



  • 問題描述:

    斐波那契數,通常用 F(n) 表示,形成的序列稱為斐波那契數列。該數列由 0 和 1 開始,后面的每一項數字都是前面兩項數字的和。也就是:

    F(0) = 0,   F(1) = 1
    F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
    

    給定 N,計算 F(N)。

    示例 :

    輸入:2
    輸出:1
    解釋:F(2) = F(1) + F(0) = 1 + 0 = 1.
    
  • 問題分析:

    由於計算任何一個第n(n >= 2)項的數都需要知道其前面兩個數,即需要知道n-1和n-2是多少,然后兩個相加得到結果,但是問題來了,要知道n-1,就要需要知道n-2,要知道n-2就需要知道n-3,會一直這樣的循環遞歸下去,一直到第一個數,第二個,第三個.......再反推回來。 那就很明顯了,大家第一時間想到的方法便是遞歸,就下來實現一下:

    方法一:遞歸實現

    public class Solution {
    	 public int fib(int n) {
         	if(n <= 1){
                return n;
            }
             return fib(n-1) + fib(n-2);
         }
    }
    

​ 問題分析:

​ 先看一下遞歸圖:

​ 由於很多數的計算都要重復很多次,效率並不高,時間復雜度達到了 O(2^n),是斐波那契數計算中 時間復雜度最大,最不可取的方法。

​ 空間復雜度:O(n),堆棧中需要的空間與 N 成正比,堆棧會跟蹤 fib(n) 的調用,隨着堆棧的不斷增長 如果沒有足夠的內存則會出現StackOverflowError異常。

​ 注:定義為int型時,最大只能求到n = 46,f(46) = 1836311903, 而 f(47) = -1323752223,因為超出了int 型數值的最大范圍。

  • 算法改進:

    使用遞歸的同時,使用記憶化方式存儲已經計算過的數據,減少不必要的重復計算,可以使時間復雜度降到 O(N),同時空間復雜度也是O(N)。具體的實現是使用一個數組,把每次計算過的值都存儲進去,當再次使用這個數的時候,直接返回,不需要再進行遞歸。

    方法二:記憶化自底向上遞歸

    public class Solution {
    	 public int fib(int n) {
         	if(n <= 1){
                return n;
            }
             int[] memo = new int[n+1];
             memo[1] = 1;
             for(int i = 2;i <= n; i++){
                 //自底向上填充數組,一直到需要的那個數
                 memo[i] = memo[i-1] + memo[i-2];
             }
             return memo[n];
         }
    }
    

方法三:使用第三方變量

class Solution {
    public int fib(int N) {
        if (N < 2) return N; 
        if (N == 2) return 1;
    
        int temp = 1;
        int result = 1;
        for (int i = 3; i <= N ; i++) {
            result= temp + result;
            temp = result - temp;
        }
        return result;
    }
}

時間復雜度瞬間降到O(1),這個我覺得應該是三個方法里面最簡單最高效的。


  • 最后:

    限於水平有限,斐波那契數的實現還有很多種方法,不能一一列舉,當其中大部分都有類似的思想。

    水文中如有不准確或是錯誤之處,還望指出。謝謝~~~

    下一篇:LeetCode.62——不同路徑


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM