# algorithms(算法)
# 1、重复计算的问题
int f(int n){
// 1.先写递归结束条件
if(n <= 2){
return n;
}
// 2.接着写等价关系式
return f(n-1) + f(n - 2);
}
看到没有,递归计算的时候,重复计算了两次 f(5)
,五次 f(4)
。。。。这是非常恐怖的,n
越大,重复计算的就越多,所以我们必须进行优化。
如何优化?一般我们可以把我们计算的结果保证起来,例如把 f(4)
的计算结果保证起来,当再次要计算 f(4)
的时候,我们先判断一下,之前是否计算过,如果计算过,直接把 f(4)
的结果取出来就可以了,没有计算过的话,再递归计算。
用什么保存呢?可以用数组或者 HashMap
保存,我们用数组来保存把,把 n
作为我们的数组下标,f(n)
作为值,例如 arr[n] = f(n)
。f(n)
还没有计算过的时候,我们让 arr[n]
等于一个特殊值,例如 arr[n] = -1
。
当我们要判断的时候,如果 arr[n] = -1
,则证明 f(n)
没有计算过,否则, f(n)
就已经计算过了,且 f(n) = arr[n]
。直接把值取出来就行了。
// 我们实现假定 arr 数组已经初始化好的了。
int f(int n){
if(n <= 1){
return n;
}
//先判断有没计算过
if(arr[n] != -1){
//计算过,直接返回
return arr[n];
}else{
// 没有计算过,递归计算,并且把结果保存到 arr数组里
arr[n] = f(n-1) + f(n-2);
reutrn arr[n];
}
}
# 2、考虑是否可以自底向上
public int f(int n) {
if(n <= 2)
return n;
int f1 = 1;
int f2 = 2;
int sum = 0;
for (int i = 3; i <= n; i++) {
sum = f1 + f2;
f1 = f2;
f2 = sum;
}
return sum;
}
这种方法,其实也被称之为递推。
← 笔记 Angular 入门笔记(超棒) →