斐波那契數列

2021-06-22 11:36:05 字數 3505 閱讀 4728

微軟面試題之一,難度係數中。

題目描述如下:

定義fibonacci 數列如下: 

/ 0 n=0 

f(n)= 1 n=1 

\ f(n-1)+f(n-2) n=2 

輸入n,用最快的方法求該數列的第n 項。

邏輯分析:

對於斐波那契數列問題,經常在各種語言書中,作為遞迴的例子,所以提起遞迴,很多程式設計師都會想到斐波那契數列,至於效率嘛。。。呵呵,***,順便一提,這貨也是讓大部分人不假思索,直言一切遞迴低效率的罪魁禍首。

這裡給出坑爹的遞迴演算法實現原始碼:

int fibonacci(int n)

該演算法效率低下的本質原因在於重複計算,我們以n=10為例,

f(10)/ \

f(9)

f(8)/\

/ \f(8) 

f(7) 

f(7)

f(6)/ \

/\f(7) 

f(6) 

f(6) f(5)

可以看出,樹中的所有節點都需要計算,而顯而易見的是,樹中存在重複節點,樹的高度為n-1,則時間複雜度為o(2^n)(等比數列求和)。

補充:這裡的計算是估算,因為並非是滿二叉樹,嚴格來講,這裡只是得到了演算法的複雜度階——指數複雜度。

這裡摘出資料結構經典書籍中的一段分析:

我們令t(n)

為函式fib(n)

的執行時間,當

n>=2

的時候我們分析可知:

t(n) = t(n-1) + t(n-2) + 2

而fib(n) = fib(n-1) + fib(n-2)

,所以有

t(n) >= fib(n)

,歸納法證明可得:

fib(n) < (5/3)^n

n>4

時,fib(n

)>= (3/2)^n

標準寫法:

顯然這個o

((3/2)^n

)是以指數增長的演算法

,基本上是最壞的情況。

其實,這違反了遞迴的乙個規則:合成效益法則。

合成效益法則(

compound interest rule

):在求解乙個問題的同一例項的時候,切勿在不同的遞迴呼叫中做重複性的工作。

所以在上面的**中呼叫

fib(n-1)

的時候實際上同時計算了

fib(n-2)

。這種小的重複計算在遞迴過程中就會產生巨大的執行時間。

2、找到了問題的所在,那麼我們的想法,顯然就是避免重複計算,實際上,不難想到,只要利用乙個迴圈,不斷遞推,便可以在o(n)的時間複雜度內完成演算法。

int fibonacci(int n)

; if(n<2)

return result[n];

int fibone = 1,fibtwo = 0;

int fibn = 0;

for(int i=2;i<=n;i++)

return fibn;

}

3、題目要求時間複雜度盡可能低,而作為面試題,顯然o(n)並非最佳解。到目前為止,我們成功避免了重複計算,那麼,如果我們想進一步降低時間複雜度,就要從數學上刪繁就簡,得到乙個最純粹的式子,而對於數列來說,只要寫出通項公式,那麼對於計算機來說,時間複雜度基本上可以看做是o(1),斐波那契數列通項公式的求法,這裡就不再多說,對於只要有一點高中數學競賽基礎的看客,想必並非難事。

**實現:

int fibonacci(int n)

注:實際上,雖然理論上時間複雜度是o(1),不過效率上還是和具體的pow,sqrt函式有關係。

4、我想對於大部分人來說,問題做到這裡,就可以結題了。不過對於斐波那契數列問題,一部分人是了解一種矩陣演算法的(我記著好像是在mit演算法導**開課看到的。。。)

我們將數列寫成:

fibonacci[0] = 0,fibonacci[1] = 1

fibonacci[n] = fibonacci[n-1] + fibonacci[n-2] (n >= 2)

可以將它寫成矩陣乘法形式:

遞推得到:

那麼,我們的目標,就是計算

問題的精髓便在於此處,我們分離出了目標,但是直觀上需要計算n次方,單純的迴圈計算,時間複雜度上並不會有所改善,依然是o(n),而對於乘方計算這一問題,實際上也是歷史悠久,沒錯,你應該想到了,利用二分法,演算法五大思想中的分治。

乘方性質: / 

a^(n/2)

*a^(n/2)

n為偶數時a^n

=\ a^((n-1)/2)*a^((n-1)/2)*a

n為奇數時

求n次方,那麼先求得n/2次方,再將結果平方一下,所以,時間複雜度o(logn)。

#include #include //2x2矩陣結構體定義

struct matrix2by2

int m_00;

int m_01;

int m_10;

int m_11;

};//矩陣乘法運算

matrix2by2 matrixmultiply

( const matrix2by2& matrix1,

const matrix2by2& matrix2

)///

//計算矩陣的n次方

// 1 1

// 1 0

///matrix2by2 matrixpower(unsigned int n)

else if(n % 2 == 0)

else if(n % 2 == 1)

return matrix;

}//斐波那契呼叫介面

斐波那契數列 斐波那契數列python實現

斐波那契數列 fibonacci sequence 又稱 分割數列 因數學家列昂納多 斐波那契 leonardoda fibonacci 以兔子繁殖為例子而引入,故又稱為 兔子數列 指的是這樣乙個數列 1 1 2 3 5 8 13 21 34 在數學上,斐波納契數列以如下被以遞推的方法定義 f 1 ...

迴圈斐波那契數列 斐波那契數列應用

什麼是斐波那契數列 斐波那契數列指的是這樣乙個數列 1,1,2,3,5,8,13,21,34,55,89,144 這個數列從第3項開始,每一項都等於前兩項之和 台階問題 有一段樓梯有10級台階,規定每一步只能跨一級或兩級,要登上第10級台階有幾種不同的走法?這就是乙個斐波那契數列 登上第一級台階有一...

斐波那契數列

1 題目描述 大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項。斐波那契數列的定義如下 輸入 輸入可能包含多個測試樣例,對於每個測試案例,輸入包括乙個整數n 1 n 70 輸出 對應每個測試案例,輸出第n項斐波那契數列的值。2 這是九度上的乙個題,要求時間限制1秒,整數的...