这个 题目有很多种解答方式,非递归,递归,优化递归,尾递归等,普通的递归十分的消耗性能,会进行很多重复的运算,所以就用上了用数组或者map做缓存。当然最优解 是用尾递归,函数的运算 在尾部 直接return
先看看最普遍的递归
public static int fab(int n) { // 分析一段代码好坏,有两个指标,时间复杂度和空间复杂度 都是:O(2^n)
if (n <= 2)
return 1; // 递归的终止条件
return fab(n - 1) + fab(n - 2); // 继续递归的过程
}
会消耗大量的性能,一般需要考虑清除
public static int noFab(int n) { // 不用递归 O(n)
// 循环
if (n <= 2)
return 1;
int a = 1;
int b = 1;
int c = 0;
for (int i = 3; i <= n; i++) {
// 移位 累加
c = a + b;
a = b;
b = c;
}
return c;
}
下面是 使用数组和 map来进行实现
public static int fab2(int n) { // 用数组来做缓存 将为了O(n),空间也降至为O(n)
if (n <= 2)
return 1; // 递归的终止条件
if (data[n] > 0) {
return data[n];
}
int res = fab2(n - 1) + fab2(n - 2); // 继续递归的过程
data[n] = res;
return res;
static int constant = 1000000007;
public static int fib(int n) {
Map<Integer,Integer> map = new HashMap<>();
return fib(n,map);
}
public static int fib(int n,Map<Integer,Integer> map) {
if(n < 2){
return n;
}
if (map.containsKey(n)){// 如果有值 那么可以直接返回
return map.get(n);
}
map.put(n -1,fib(n - 1,map));
map.put(n -2,fib(n - 2,map));
int res = (fib(n - 1,map) + fib(n - 2,map)) % constant;
return res;
}
最后展示 尾递归进行的操作,时间和空间复杂的都是O(n)
class Solution {
int constant = 1000000007;
public int fib(int n) {
return fib(1,1,n);
}
public int fib(int pre,int res,int n) {
if (n < 1) return 0; // 递归的终止条件
if (n <= 2) return res;
return fib(res % constant, (pre + res) % constant, n - 1);
}
}
尾递归使用理解 在个人看来很难理解,很难使用,还需要大量的实践和练习才能熟练,加油