记忆化递归
在递归的过程中难免会存在相同的值,相同的计算过程,那么重复的计算难免会浪费资源。因此将这类值存储起来,在递归的过程中使用,这样的过程称为记忆化递归。
递归例子
一只青蛙每次能跳1级或者2级的台阶,现在计算跳到n级台阶的跳法有多少种?
分析
对于n级台阶而言,青蛙倒数最后第二次,一定跳到的是n-1,或者是n-2的台阶。跳到n-1或者n-2的跳法数相加便是跳到n级的跳法数。那么套娃递归公式就出来了
f
(
n
)
=
f
(
n
−
1
)
+
f
(
n
−
2
)
f(n)=f(n-1)+f(n-2)
f(n)=f(n−1)+f(n−2)
如果为5级台阶
5
4 3
3 2 2 1
1 2
由此得出n-k = 1或者2是为结束条件,跳1阶台阶跳法为1种,2阶台阶跳法为2种
代码
function step(n){
if(n==2){
return 2
}
if(n==1){
return 1
}
return step(n-1)+step(n-2)
}
//测试
let pre = process.uptime();
console.log('跳法:',step(5)) //8种
let err = process.uptime() - pre;
console.log(err * 1000)
递归优化
在以上例子中,对于5级台阶,每次都需要重复计算相同台阶的跳法,这样使得效率很低。
因此可以使用空间换取效率
let cache = [, 1, 2]
function step(n) {
if (!cache[n] && cache[n] != 0) {
cache[n] = step(n - 1) + step(n - 2);
}
return cache[n]
}
//测试
let pre = process.uptime();
console.log('跳法:',step(70))
let err = process.uptime() - pre;
console.log(err * 1000)
前后结果对比
n = 100
未优化,时间太长
优化后,10m以内