因為最近在解 Leetcode 的 91. Decode Ways


要用到 Fibonacci sequence 來解,就我所知上次解 70Climbing Stairs 的時候,
用 recursive 求解 Fibonacci sequence 的時候會 TLE。
(所以我就偷懶跑去用 Python3 解大數)


這次再遇到應該是要進步了xDDD


正文開始:

Fibonacci sequence 會長這個樣子:



根據基本定義,第 N 個 Fibonacci value 等於前兩個 Fibonacci value 相加,
我們便可以得到公式:



得到公式以後把它擴展成 轉移矩陣 M 的形式,
因為我們把前兩項當作初始值,所以 轉移矩陣 M 的指數會減二:



所以我們現在只要計算 M 的 (n-2) 次方就能得到第 N 個 Fibonacci value。
(左上角的 M00 會等於 第N個 Fibonacci value

此時的計算複雜度為:O(n)

以第 45 個 value 值來比較,此方法已經比遞迴快很多了xD




但是我還要教你一個威力加強版外掛:平方求冪
(左岸又稱快速冪 or double-and-add


我們在這裡要用平方求冪去優化轉移矩陣 M。


平方求冪的想法是把任何高階指數都化為與指數二有關的指數和,
屁話一堆直接看數學比較快:


如果你說 n 是 odd 怎麼辦?
啊不簡單?直接減一再乘回去R~:




這樣的好處是能大大的減少計算量,數學意義上來說是二分搜尋法,
以找 n = 16 舉例,

沒有平方求冪的版本會很老實地計算十五次乘法,
而有平方求冪外掛的版本會跳著算:



像是圖中有幾個節點,就計算幾次,
每次都是跟自己相乘,所以實際上只要算黃色螢光筆那條路徑,
不必考慮其他條黑色路徑。

由此可以 16 = 2^4,所以有 4 個節點,只需計算 4次。
此時又可推導出 計算複雜度為:O(logn)
(log 以 2 為底。)


用 C++ 實現的程式碼我放在這裡


有興趣的可以直接拿來用,不用再造車輪了xD

感謝各位

By wuyiulin

喜歡騎單車的影像算法工程師

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *