斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、一、一、二、三、五、八、1三、2一、3四、……在数学上,斐波纳契数列以以下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)
百度百科关于斐波那契数列的来源请参见兔子问题根据其定义咱们能够很方便的构建出该数列的数据结构实现。web
这种写法是最多见的,可是可能会形成栈溢出(每一次方法调用,都会有一个栈帧),这个方法不是很好,由于有大量的重复计算数组
/** * 返回斐波那契数第n个值,n从0开始 * 实现方式,基于递归实现 * @author zxy * @since 2018年8月18日上午9:41:30 */ public static int getFib(int n){ if(n < 0){ return -1; }else if(n == 0){ return 0; }else if(n == 1 || n ==2){ return 1; }else{ return getFib(n - 1) + getFib(n - 2); } }
递归是最简单的实现方式,但递归有不少的问题,在n的值很是大时,会占用不少的内存空间
递归的主要缺点数据结构
既然该数列定义F(n)=F(n-1)+F(n-2)(n≥2,n∈N*),那么咱们能够从头至尾进行计算,先计算前面的值,而后逐步算出第n个值。svg
使用循环的方式去解决,避免的递归的重复计算code
/** * 返回斐波那契数第n个值,n从0开始 * 实现方式,基于变量实现 * @author zxy * @since 2018年8月18日上午9:41:30 */ public static int getFib2(int n){ if(n < 0){ return -1; }else if(n == 0){ return 0; }else if (n == 1 || n == 2){ return 1; }else{ int c = 0, a = 1, b = 1; for(int i = 3; i <= n; i++){ c = a + b; a = b; b = c; } return c; } }
从上面的实现中咱们定义了3个变量a、b、c其中c=a+b,而后逐步进行计算从而获得下标为n的值。
既然咱们能够定义变量进行存储,那么一样咱们还能够定义一个数组,该数组的每个元素即一个斐波那契数列的值,这样咱们不只能获得第n个值,还能获取整个斐波那契数列。xml
以空间换时间递归
/** * 返回斐波那契数第n个值,n从0开始 * 实现方式,基于数组实现 * @author zxy * @since 2018年8月18日上午9:41:30 */ public static int getFib3(int n){ if(n < 0){ return -1; }else if(n == 0){ return 0; }else if (n == 1 || n == 2){ return 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]; } return fibAry[n]; } }
还有一种写法是,是使用hashMap将数据都存储下来,hashMap的写法其实相似于上面的数组形式,就不单独写出来了内存