举例
一个数从0开始,依次累加 每次可以加1或者2,到n的话有多少种累加方法
如 1=0+1 【1种】
2=0+1+1或0+2 【2种】
3=0+1+1+1或0+1+2或0+2+1 【3种】
4=0+1+1+1+1或0+1+1+2或0+1+2+1或0+2+1+1或2+2 【5种】
5=0+1+1+1+1+1或0+1+1+1+2或0+1+1+2+1或0+1+2+1+1或0+2+1+1+1或0+2+1+2或0+2+2+1或0+1+2+2 【8种】
。。。
总结算式 n=2时候f(n)=f(n-2)+f(n-1)
// 算式求解得出以下递归算法
function f(n) {
if (n===1 || n===2){
return n
}
return f(n-1)+f(n-2)
}
console.log(f(1),f(2),f(3),f(4),f(5))
以下为递归的过程
以上代码在运算相同值时候,出现重复计算
如f(5)=f(4)+f(3)其中f(4)=f(3)+f(2),f(3)=f(2)+f(1),f。。。
其中f(3)重复计算了,在n超大时,那么就会进行超级多的重复计算,导致性能降低
优化-记忆化递归// 初始化n为1和n为2
let memoryArr = [0,1,2]
function memoryF(n) {
if (memoryArr[n]){
return memoryArr[n]
}
return memoryArr[n] = memoryF(n-1)+memoryF(n-2)
}
console.log(memoryF(1),memoryF(2),memoryF(3),memoryF(4),memoryF(5))
以下是它的递归过程
由于f(2)与f(1)已经初始化,那么它只计算了一次的f(5)、f(4)、f(3) 未造成重复的计算,而是把第一次计算的结果储存在数组,下次遇到相同的再取出
在特殊情况下,建议把计算的值存入对象或者map中,当前业务使用数组刚好合适
比较function f(n) {
if (n===1 || n===2){
return n
}
console.log('f计算了')
return f(n-1)+f(n-2)
}
console.log(f(1),f(2),f(3),f(4),f(5))
//通过记忆化递归
// 初始化n为1和n为2
let memoryArr = [0,1,2]
function memoryF(n) {
if (memoryArr[n]){
return memoryArr[n]
}
console.log('memoryF计算了')
return memoryArr[n] = memoryF(n-1)+memoryF(n-2)
}
console.log(memoryF(1),memoryF(2),memoryF(3),memoryF(4),memoryF(5))
记忆化递归给了一个很满意的结果