解法一:暴力递归(O^2)
class Solution {
public int fib(int n) {
// 解法一: 暴力递归 O(n^2)
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fib(n - 2) + fib(n - 1);
}
}
解法二:动态规划 O(n)
class Solution {
public int fib(int n) {
//解法二: 动态规划 O(n)
//只维护 pre 和 next两个指针,分别指向斐波那契数列第n-1以及n项,自下向上的动态规划
if (n <= 1) {
return n;
}
int pre = 0;
int next = 1;
int ret = 0;
for (int i = 2; i <= n; i++) {
ret = pre + next;
pre = next;
next = ret;
}
return ret;
}
}
解法三:记忆化搜索(递归实现动态规划) O(n)
class Solution {
// 增加 cache 记录,避免重复递归
int[] cache = new int[40];
public int fib(int n) {
// 解法三: 记忆化搜索 O(n)
if (n <= 1) {
return n;
}
if (cache[n] != 0) {
return cache[n];
}
cache[n] = fib(n-2) + fib(n-1);
return cache[n];
}
}
解法四:打表 O(1)
class Solution {
static int[] cache = new int[40];
// 静态代码块,属于类,只计算一次。
static {
cache[0] = 0;
cache[1] = 1;
for (int i = 2; i < cache.length; i++) {
cache[i] = cache[i - 2] + cache[i - 1];
}
}
// 解法四:打表 O(1)
public int fib(int n) {
return cache[n];
}
}
其实还有其他解法,如矩阵快速幂,通项公式等,后面再补充。