先看下百度百科對斐波拉契數列的定義:
斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列:1、1、2、3、5、8、13、21、34、……在數學上,斐波納契數列以如下被以遞歸的方法定義:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) 反正就是一句話:斐波拉契牛逼。
第一種數組實現方法:基於數組實現
/**
* @author 薛定諤的貓
* 斐波拉契數列數組實現
* 求前二十項*/
public class Main {
public static void main(String[] args) {
getFib(20);
}
public static int getFib(int n){//核心函數
if (n<0) {
return -1;//小於0是沒有意義的
}else if (n == 0) {
return 0;//等於0其實也沒什么意義
}else if (n == 1||n == 2) {
return 1;//第一項和第二項都是1
}else {
int[] fibAry = new int[n + 1];
fibAry[0] = 0;
fibAry[1] = fibAry[2] = 1;
for(int i = 3;i<=n;i++) {
fibAry[i] = fibAry[i-1] + fibAry[i-2];//當前項等於后一項加上后兩項
System.out.println("第" + i + "項"+fibAry[i]);//輸出當前項
}
return fibAry[n];//返回當前項
}
}
}
第二種實現方法:基於變量實現
/**
* @author 薛定諤的貓
* 斐波拉契數列變量實現
* 求前二十項*/
public class Main {
public static void main(String[] args) {
getFib(20);
}
public static int getFib(int n){//核心函數
if (n<0) {
return -1;//小於0是沒有意義的
}else if (n == 0) {
return 0;//等於0其實也沒什么意義
}else if (n == 1||n == 2) {
return 1;//第一項和第二項都是1
}else {
int temp = 0;//當前項變量
int a = 1;//第一項
int b = 1;//第二項
for(int i = 3;i<=n;i++) {
//變量互換值
temp = a+b;//當前項等於前兩項相加
a = b;//前兩項互換值
b = temp;//當前項賦值給前一項
System.out.println("第" + i + "項"+temp);//輸出當前項
}
return temp;//返回當前項
}
}
}
第三種實現方法:遞歸實現(用遞歸的都是神)
遞歸定義:簡單的說就是自己調用自己。
/**
* @author 薛定諤的貓
* 斐波拉契數列變量實現
* 求前二十項
* 這種方法最簡單,但是最占用內存,特別是當n很大的時候
*
*
* 為什么遞歸得效率低?
* 遞歸效率低是函數調用的開銷導致的。在一個函數調用之前需要做許多工作,
* 比如准備函數內局部變量使用的空間、搞定函數的參數等等,這些事情每次調用函數都需要做
* ,因此會產生額外開銷導致遞歸效率偏低,所以邏輯上開銷一致時遞歸的額外開銷會多一些當然了,
* 通過有意識的組織代碼的寫法可以把某些遞歸寫成尾遞歸,尾遞歸可以進行特殊的優化所以效率
* 會比普通的遞歸高一些,也不會因為遞歸太多導致棧溢出遍歷樹還不用遞歸的話,那么人肉寫一個棧
* +深度優先遍歷或者人肉隊列+廣度優先遍歷,再輔以黑魔法給棧或者隊列提速,應該會比遞歸快一些,
* 加速幅度和語言和寫法相關,但在大多數情況下我覺得是得不償失的,花了很大精力很可能效率提升不
* 明顯
*
* 此回答轉自知乎
* */
public class Main {
public static void main(String[] args) {
for(int i = 1;i<=20;i++) {
System.out.println("第" +i + "項" + getFib(i));
}
}
public static int getFib(int n){//核心函數
if (n<0) {
return -1;//小於0是沒有意義的
}else if (n == 0) {
return 0;//等於0其實也沒什么意義
}else if (n == 1||n == 2) {
return 1;//第一項和第二項都是1
}else {
return getFib(n-1) + getFib(n-2);//返回當前項,核心遞歸
}
}
}
最后說一句,斐波拉契牛逼。
