什麼是斐波那契數列,1,1,2,3,5,8,13...這樣乙個數列就是斐波那契數列,求第n項的值。
一、經典求法
觀察數列可得,除了第一項和第二項,所有的數列的值都是前一項和前一項的前一項的加和,轉換成函式也就是f(n) = f(n-1) + f(n-2)
public static int f1(int n) else if(n == 1 || n == 2)
return f1(n-1) + f1(n-2);
}
顯然,遞迴n次,時間複雜度o(2^n),太恐怖,所以,必須優化。
二、順序求法
因為斐波那契數列可以從左到右順序的求出每一項的值,因此只需要順序計算到n項即可,時間複雜度為o(n)的,我們可以把它看成在單鏈表的最後插入乙個右最後乙個和倒數第二個指標指向的值來決定的。
public static int f2(int n) else if(n == 1 || n == 2)
int res = 1;
int pre = 1;
int temp = 0;
for(int i = 3; i < n; i++)
return res;
}
三、狀態矩陣相乘求法
這是乙個時間複雜度為o(log n)的演算法。因為斐波那契數列在n大於等於三的時候嚴格遵守遞推數列f(n) = f(n-1) + f(n-2),而對於乙個二階的遞推數列來說,我們可以用矩陣乘法來表示,且狀態矩陣是2階的方陣:
這個矩陣是怎麼得到的呢,其實回顧一下我們所學的遇到乙個遞推公式,如何求通項公式的問題,是不是就是構造乙個等比數列啊,然後換元累加求解,舉個例子,溫習一下:
使用特徵方程計算:
可以看到,這兩種方法計算的結果相同,且都是正確的,但使用特徵方程求解,十分方便.使用特徵方程的乙個問題是,如何計算得到遞推公式的特徵方程,
如上圖,計算乙個遞推公式的通項公式,只要將c1和c2的值帶入r^2 = c1 * r + c2即可,然後用上述的方法求解通項公式即可.注意,上述方法僅針對
這種形式的遞推公式.
原理解決,下面繼續看具體求法:
把斐波那契數列的前四項f(1) = 1、f(2) = 1、f(3) = 2、f(4) = 3帶進去可得狀態矩陣的為:
當求出狀態矩陣之後,當n >= 2時,原來的公式可簡化為:
(f(3),f(2))= (f(2),f(1))*a = (1,1)*a
(f(4),f(3))= (f(3),f(2))*a = (1,1)*a^2
(f(n),f(n-1))= (f(n-1),f(n-2))*a = (1,1) *a^(n-2)
所以其斐波那契數列n項和的問題就轉化為如何用乙個最快的方法求乙個矩陣的n次方的問題,而求矩陣n方的問題顯然能夠在o(log n)時間內解決的問題,因為乙個矩陣的實質其實就是乙個值,假設這個數為a,如何快速的求a^75次冪的值,因為75次冪的二進位制形式為1001011,那麼a^75就可以寫成a^64*a^8*a^2*a^1,在這過程中,我們先求出a的一次冪,再求2次冪,在根據2次冪去求4次冪以此類推,最後根據32次冪求出64次冪,即75的二進位制形式共有多少位我們就使用了幾次乘法,而且只乘相位上為1的位置即可。
**實現:
//特徵矩陣法
//求矩陣m的p次冪的值
public static int matrixpower(int m, int p)
//臨時矩陣
int tmp = m;
for (; p != 0; p >>= 1)
//等於0 的時候我臨時矩陣自己乘一下
tmp = mulimatrix(tmp, tmp);
}return res;
}//兩矩陣相乘
public static int mulimatrix(int m1, int m2) }}
return res;
}//利用矩陣乘法求解斐波那契數列第n項的值
public int f3(int n)else if(n == 1 || n == 2)
//狀態矩陣
int base = ,};
//最後的結果需要求矩陣的n-2次
int res = matrixpower(base, n-2);
return res[0][0] + res[1][0];
}
三種方法實現斐波那契數列
問題描述 編寫程式在控制台輸出斐波那契數列前t項,每輸出5個數換行 第一種方法 耗時比較短 publicstaticvoidtest1 long t longend system.currenttimemillis system.out.println end start 第二種方法 耗時太長沒有測...
實現斐波那契數列的三種方法
斐波那契數列又稱 分割數列。它的特點是從第3個數開始,每乙個數都等於前面兩個數相加。例 0 1 1 2 3 5 8 13 21.從上我們可以總結出以下規律 當n 0時 f n 0 當n 1時 f n 1 當n 1時 f n f n 1 f n 2 那我們如何求出這個數列中第n個數是多少呢?一 以指標...
三種方法求斐波拉契數列
斐波那契數列 斐波那契數列 1,1,2,3,5,8,13,21,34,55,89,144,如果設f n 為該數列的第n項 n n 那麼這句話可以寫成如下形式 f n f n 1 f n 2 顯然這是乙個線性遞推數列。include 遞迴的方法求斐波拉契數列 優點簡單明瞭,缺點當所求數過大時占用記憶體...