斐波那契数列(Fibonacci sequence),又称黄金分割数列,是一个著名的数列,由意大利数学家列昂纳多·斐波那契(Leonardo 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属于自然数集。斐波那契数列不仅在数学中有广泛的应用,还在日常生活中有许多实例,如植物的叶子排列、花朵的花瓣数量等。
此外,斐波那契数列与黄金分割有密切的联系,当数列项数趋向于无穷大时,相邻两项的比值逐渐逼近黄金分割比0.618。
从0开始
0、1、1、2、3、5、8、13、21、34、55、89、144 ...
公式如下
F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)
其四种实现方式如下:
- 单纯的递归实现
- 通过引入一个“记忆空间”做剪枝操作
- 优化掉递归的实现方式
- 优化掉“记忆空间”
public class DPTest {
public static void main(String[] args) {
System.out.println(fib1(6));
System.out.println("纯递归次数:" + fib1Count);
System.out.println(fib2(6));
System.out.println("优化重复计算后次数:" + fib2Count);
System.out.println(fib3(6));
System.out.println(fib4(6));
}
static AtomicInteger fib1Count = new AtomicInteger();
// 递归
public static int fib1(int n) {
fib1Count.addAndGet(1);
return n <= 1 ? n : fib1(n - 1) + fib1(n - 2);
}
static Map<Integer, Integer> mem = new HashMap<>();
static AtomicInteger fib2Count = new AtomicInteger();
// 递推(递归+记忆化)
public static int fib2(int n) {
fib2Count.addAndGet(1);
if (n <= 1) {
return n;
}
if (!mem.containsKey(n)) {
mem.put(n, fib2(n - 1) + fib2(n - 2));
}
return mem.get(n);
}
// DP- 时间和空间 O(n)
public static int fib3(int n) {
if (n <= 1) {
return n;
}
int[] mem2 = new int[n + 1];
mem2[0] = 0;
mem2[1] = 1;
for (int i = 2; i <= n; i++) {
mem2[i] = mem2[i - 1] + mem2[i - 2];
}
return mem2[n];
}
// DP空间优化- 时间O(n) 空间O(1)
public static int fib4(int n) {
if (n <= 1) {
return n;
}
int first = 0;
int second = 1;
for (int i = 2; i <= n; i++) {
int temp = first + second;
first = second;
second = temp;
}
return second;
}
}