1.如果讓我們遞迴解決,我們通常使用這一段**來解決斐波那契數列問題
int
fib(
int n)
確實簡單又好懂,可是這段**細思極恐,時間複雜度是指數級的o(2n)。這可了不得。
那麼為什麼它的時間複雜度這麼高呢?
我們畫出遞迴樹
注意:fib8『和fib8是一樣的,筆者不太會用這個圖所以只能這樣了。
我們可以看到當左邊的子樹已經計算了fib8後右子樹又計算了一遍,計算機在做大量的重複工作。
因為如果讓我這個菜鳥計算2343+2312後讓我再次計算這個加法,我肯定會在我的演草紙上找我之前計算的結果。如果讓我做一百道複雜加法題,有大量重複計算的話,我肯定會先在我的演草紙上找一找有沒有已經計算了的。
對,這就是備忘錄,我們給計算機乙個備忘錄。它就可以不用重複計算了。
2.備忘錄解法
#include
#include
using
namespace std;
intfib
(int n)
;int
solve
(vector<
int>
&memo,
int n)
;int
main()
// 其實我們定義乙個函式也沒問題,但這樣分開更清楚
intfib
(int n)
// 傳入備忘錄的位址
intsolve
(vector<
int>
&memo,
int n)
這樣一來我們把乙個冗雜的樹就簡化了。簡化成fib10 -> fib9 -> fib8 … ->fib 1
這樣我們的時間複雜度就從指數級的到了o(n) (乙個有n個子問題,每個子問題只需要一次計算)
空間複雜度o(n),只用了乙個容器來當備忘錄。
斐波那契數列 遞推 遞迴 備忘錄 動態規劃
當n 0時,f n 0 當n 1時,f n 1 當n 1時,f n f n 1 f n 2 遞迴演算法 cpp view plain copy intfun intn 備忘錄方法 cpp view plain copy include using namespace std const intn 1...
斐波那契數列 動態規劃 遞迴(帶備忘錄)
大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項 從0開始,第0項為0,第1項是1 n 39 直接由斐波那契數列的定義f n f n 1 f n 2 可以得到遞迴的公式,為了避免重複求解已經結果的問題,可以使用備忘錄 即陣列 將備忘錄初始化為 1,遞迴時進行判斷,若已經求...
斐波那契數列解法
方法一 常規解法 def demo month 定義變數 a,b分別表示一月和二月的數目 a 0 a為第乙個數值 b 1 b為第二個數值 定義乙個計數器 i 0 while i month 列印每次的數值 print a a,b b,a b i 1 nume demo 3 方法二 函式的遞迴 def...