
黑馬程序員
微信號:heiniu526
傳智播客旗下互聯網資訊,學習資源免費分享平臺
大家在面試過程中經常會考到斐波那契數列,斐波那契數列(Fibonacci)最早由印度數學家Gopala提出,而第一個真正研究斐波那契數列的是意大利數學家 Leonardo?Fibonacci,斐波那契數列的定義很簡單,用數學函數可表示為:
數列從0和1開始,之后的數由前兩個數相加而得出,例如斐波那契數列的前10個數是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34。
用 Python 實現斐波那契數列常見的寫法有三種,各算法的執行效率也有很大差別,在面試中也會偶爾會被問到,通常面試的時候不是讓你簡單的用遞歸寫寫就完了,還會問你時間復雜度怎樣,空間復雜度怎樣,有沒有可改進的地方。

所謂遞歸就是指函數的定義中使用了函數自身的方法。
遞歸是一種代碼最簡潔的方法,但它是效率非常低,因為會出現大量的重復計算,時間復雜度是:O(1.618 ^ n),1.618是黃金分割。同時受限于 Python 中遞歸的最大深度是1000,所以用遞歸來求解并不是一種可取的辦法。

遞推法就是從0和1開始,前兩項相加逐個求出第3、第4個數,直到求出第n個數的值。
這種算法的時間復雜是O(n),呈線性增長,如果數據量巨大,速度越到后面會越慢。上面兩種方式都是使用分而治之的思想,就是把一個大的問題化小,然后利用小問題的求解得到目標問題的答案。

線性代數》是大學計算機專業低年級的課程,這門課教的就是矩陣,那時候覺得這東西學起來很枯燥,沒什么用處,工作后你才發現搞機器學習、數據分析、數據建模時大有用處,書到用時方恨少。其實矩陣的本質就是線性方程式。
斐波那契數列中兩個相鄰的項分別為:F(n) 和 F(n - 1),如果把這兩個數當作一個2行1列的矩陣可表示為:
因為 F(n) = F(n-1)+F(n-2),所以就有:
通過反推,其實它是兩個矩陣的乘積得來的:
依此類推:
最后可推出:
因此想要求出F(n)的值,只要能求出右邊矩陣的n-1次方的值,最后求得兩矩陣乘積,取新矩陣的第一行的第一列的值即可,比如n=3時:
可以得知F(3)的值2,F(2)的值為1,因為冪運算可以使用二分加速,所以矩陣法的時間復雜度為 O(log n)。
我們可以用科學計算包 numpy 來實現矩陣法:

3種不同的算法效率對比:
從上面圖可以看出遞歸法效率驚人的低,矩陣法在數據量比較大的時候才突顯出它的優勢,遞推法隨著數據的變大,所花的時間也越來越大。


▼點擊?加程序員交流群