先看下百度百科对斐波拉契数列的定义:
斐波那契数列(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);//返回当前项,核心递归
}
}
}
最后说一句,斐波拉契牛逼。