1. 基本定義
又稱為“兔子數列”,指的是這樣一個數列:1、1、2、3、5、8、13、21、34、……在數學上,斐波那契數列以如下被以遞推的方法定義:F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)
2. 代碼實現
2.1 基本遞歸代碼(不實用)
1 int Fibonacci(int n) { 2 if( n == 0 ) 3 return 0; 4 if ( n == 1 ) 5 return 1; 6 else 7 return Fibonacci(n - 2) + Fibonacci(n - 1); 8 }
解析:以上斐波那契數列是基本的遞歸方法,但不實用,因為在程序運行時,一旦 n 值過大易造成堆棧溢出狀況而且重復嚴重,舉例:n=4,看看程序怎么跑的:
Fibonacci(4) = Fibonacci(3) + Fibonacci(2);
= Fibonacci(2) + Fibonacci(1) + Fibonacci(1) + Fibonacci(0);
= Fibonacci(1) + Fibonacci(0) + Fibonacci(1) + Fibonacci(1) + Fibonacci(0);
對於程序而言每一次的遞歸都是未知的,光是F(1) 便循環了3次之多,
故不推薦!
2.2 進階遞歸代碼(矩陣快速冪)
1 int Fibonacci(int n) { 2 if( n == 0 ) 3 return 0; 4 else if ( n == 1 || n == 2) 5 return 1; 6 else if ( n == 3) 7 return 2; 8 else 9 return 3* Fibonacci(n - 3) + 2* Fibonacci(n - 4); 10 }
解析:該進階方法通過斐波那契數列的一個簡單規律可以使得冗余程度不再像第一個那般復雜重復,節省空間。矩陣快速冪詳解參見:https://www.cnblogs.com/MMMMMMMW/p/12300262.html
2.3 動態規划版代碼
1 int Fibonacci(int n) { 2 int f = 0, g = 1; 3 while(n -- > 0) { 4 g += f; 5 f = g - f; 6 } 7 return f; 8 }
解析:該方法中循環 n 次,因為第 n 個數字是前 n 個數字以規律相加得來,定義的 f 和 g 表示每一次第 n 個數相加時的 n - 1 和 n - 2 位 ,f 在每次運算過后都要 被 g 減去之前的數,方可得到第 n 位的數字。
圖解: