斐波那契數(shù)列定義:
斐波那契數(shù)列指的是這樣一個(gè)數(shù)列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987........
這個(gè)數(shù)列從第3項(xiàng)開始,每一項(xiàng)都等于前兩項(xiàng)之和。
1.常規(guī)解法---遞歸
根據(jù)第n項(xiàng)的值等于n-1和n-2的值之和這個(gè)特性,代碼如下:
public class Fibonacci {
public static int Fib(int N) {
if (N < 3)
return 1;
else
return Fib(N - 1) + Fib(N - 2);
}
public static void main(String[] args) {
int num = Fib(10);
System.out.println(num);
}
}
這種方法的最大缺陷就是重復(fù)計(jì)算的次數(shù)太多了,導(dǎo)致時(shí)間復(fù)雜度高
,比如當(dāng)n=3時(shí)
1. Fib1(3)=Fib1(2)+Fib1(1)
2. 計(jì)算Fib1(1) 第一次計(jì)算
3. 計(jì)算Fib1(2) 第二次計(jì)算
4. 計(jì)算Fib1(2)+Fib1(1) 第三次計(jì)算
就需要計(jì)算三次,時(shí)間復(fù)雜度:O(2^N),空間復(fù)雜度:O(N)
2.遞歸+全局?jǐn)?shù)組
由于第一種方式重復(fù)計(jì)算的次數(shù)過(guò)多,為了避免我們可以建立一個(gè)類似于全局變量的數(shù)組來(lái)存儲(chǔ)已經(jīng)計(jì)算出來(lái)的數(shù)列項(xiàng),在每一次遞歸時(shí)直接取出來(lái)前兩個(gè)值,省去重復(fù)計(jì)算。代碼如下:
public class FibArray {
public static int[] array = new int[20];
public static int Fib(int n) {
if (n <= 1)
return n;
if (array[n] != 0)
return array[n];
else
return array[n] = Fib(n - 1) + Fib(n - 2);
}
public static void main(String[] args) {
int num = Fib(10);
System.out.println(num);
}
}
此種方法相當(dāng)于緩存了前面的值,很大程度的減小了第一種方法(遞歸實(shí)現(xiàn)斐波那契數(shù)列)的時(shí)間復(fù)雜度,缺點(diǎn)是需要另外開辟數(shù)組內(nèi)存,數(shù)組的長(zhǎng)度是固定的,不能動(dòng)態(tài)調(diào)整。
時(shí)間復(fù)雜度:0(N),
空間復(fù)雜度:0(N)
3.循環(huán)實(shí)現(xiàn)
public class FibForEach {
public static int Fib(int n) {
int first = 1;
int second = 1;
int ret = 0;
for (int i = 3; i <= n; i++) {
ret = first + second;
first = second;
second = ret;
}
return second;
}
public static void main(String[] args) {
int num = Fib(10);
System.out.println(num);
}
}
循環(huán)的方式省去了數(shù)組這個(gè)不定的因素,優(yōu)點(diǎn):時(shí)間復(fù)雜度和空間復(fù)雜度最低,而且可讀性高
時(shí)間復(fù)雜度:O(N)
空間復(fù)雜度:O(1)(創(chuàng)建了四個(gè)對(duì)象,是常數(shù),所以可忽略不計(jì))
此種方法是目前的"最優(yōu)方法",如果有更好的歡迎留言交流。