寫乙個函式,輸入n,求斐波那契數列的第n項。
斐波那契數列的定義如下
課本的上為了講解遞迴演算法,經常用這個例子。讓我們看一下它的實現
package algorithm;
public
class fibonacci_recursion
public
static
void main(string args) }
因為隨著 n 的大小變化,返回值會越來越大,防止越界,這裡使用 long 而不是 int 型別。
我們知道,遞迴演算法的執行時間是隨著 n 的大小變化而成指數遞增。
博主在自己的機器上測試。求 4 的斐波那契項,用時可能可以忽略, 0 ms;求 40 的斐波那契項 用時 534 ms; 然後 求 50 呢,機器的風扇開始響了,幾十秒過去了,都沒結果。
可見,使用遞迴求斐波那契數列項,容易理解,但是效率真的很 bad 。
因為,當我們求 fibonacci(10) 的時候,要求 fibonacci(9) 和 fibonacci(8); 同樣,求 fibonacci(9) 的時候要先求 fibonacci(8) 和 fibonacci(7)... 這下面會有很多重複計算的過程。比如幾乎計算所有的項都算了 fibonacci(1)+fibonacci(2)。
如果我們把這個用樹形結構來表示,可以看做乙個根節點在上的自上而下的二叉樹,每次計算都會重複計算很多子節點。
如果我們不使用遞迴演算法,而是使用常規的解法,效果是不是會高很多呢?至少要把時間複雜度給降下來吧。
常規解法怎麼做呢?
如果是求 fibonacci(10),我們先把 求 fibonacci(1), fibonacci(2),然後根據前兩者求 fibonacci(3),然後再 求 fibonacci(4),一直求到 fibonacci(10) 。
這其實只需要乙個 for 迴圈,所有,時間複雜度為 o(n)。
**實現
package algorithm;
public
class fibonacci_linear
return num2;
}public
static
void main(string args) }
由於時間複雜度為 o(n) ,也就是說,隨著 n 的變大我們的時間都是可以忽略的,無論是 fibonacci(40) ,fibonacci(400) ,fibonacci(4000),fibonacci(4000000) 都是可以計算且時間都很短的。
比如求 fibonacci(4000000) 最終結果如下
6558868233897966651
可見該方法比第一種的遞迴好多少,這也應該是面試官所青睞的。
待補充...
斐波那契數列解法
方法一 常規解法 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...
斐波那契數列解法
1 概念 在數學上,費波那契數列是以遞迴的方法來定義 f0 0 f1 1 fn fn 1 fn 2 n 2 用文字來說,就是費波那契數列由0和1開始,之後的費波那契係數就是由之前的兩數相加而得出。首幾個費波那契係數是 0,1,1,2,3,5,8,13,21,34,55,89,144,233 oeis...
斐波拉契數列的三種解法
斐波那契數列 f n f n 1 f n 2 n 2 f 0 0 f 1 1 即有名的兔子繁衍問題。斐波那契數列共有三種解法,因而寫這篇文章總結一下。1.遞迴求解 遞迴求解比較簡單,是大家常見的一種解法。int fibonacci int n if n 1 return fb n 1 fb n 2 ...