斐波那契數列問題


大家都知道斐波那契數列(0 1 1 2 3 5 8 13 21 34 55  ......)

現在要求輸入一個整數n,請你輸出斐波那契數列的第n項。


分析:

這個題可以說是迭代(Iteration) VS 遞歸(Recursion) f(n) = f(n-1) + f(n-2),第一眼看就是遞歸啊,簡直完美的遞歸環境,遞歸肯定很爽,這樣想着關鍵代碼兩三行就搞定了,注意這題的n是從0開始的:
public class Solution {
public int Fibonacci(int n) {
if(n <= 1)
return n;
else
<span style="white-space:pre"></span> return Fibonacci(n-1)+Fibonacci(n-2);
}
}

然而並沒有什么用,測試用例里肯定准備着一個超大的n來讓Stack Overflow,為什么會溢出?因為重復計算,而且重復的情況還很嚴重,舉個小點的例子,n=4,看看程序怎么跑的:Fibonacci(4) = Fibonacci(3) + Fibonacci(2);                    = Fibonacci(2) + Fibonacci(1) + Fibonacci(1) + Fibonacci(0);
                    = Fibonacci(1) + Fibonacci(0) + Fibonacci(1) + Fibonacci(1) + Fibonacci(0);
由於我們的代碼並沒有記錄Fibonacci(1)和Fibonacci(0)的結果,對於程序來說它每次遞歸都是未知的,因此光是n=4時f(1)就重復計算了3次之多。那么如何求解呢,動態規划似乎不錯,關於動態規划三個條件:最優子結構、無后效性、子問題重疊這些就不談了,因為理論性太強了。下例是一個簡單的動態規划,以一定的空間代價避免代價更大的重復計算的棧空間浪費:
public class Solution {
public int Fibonacci(int n) {
if(n <= 1) return n;
int[] record = new int[n+1];
record[0] = 0;
record[1] = 1;
for(int i = 2; i < n+1; i ++){
record[i] = record[i-1] + record[i-2];
}
return record[n];
}
}

雖然看起來很蠢,空間浪費了sizeof(int)*(n-1),但是對於那個超大n的測試用例應該是可以通過了,時間復雜度也達到了O(n)。



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: