线性递推式问题-斐波那契数列

一、递归

function Fibonacci(n) {
    if (n === 1 || n === 2) {
        return 1
    }
    return Fibonacci(n-1) + Fibonacci(n-2)
}

递归最大的问题就是当调用帧过多时致使内存溢出html

二、闭包-把运算结果存储在数组里,避免重复计算

function Fibonacci(n) {
    let arr = [0, 1] // 把计算过的结果存储在数组里
    return (n) => {
        if (arr[n] === undefined) {
            arr[n] = Fibonacci(n-1) + Fibonacci(n-2)
        }
        return arr[n]
    }
}

三、循环

function Fibonacci(n) {
    let res1 = 1
    let res2 = 2
    if (n === 1 || n === 2) {
        return res2
    }
    for(let i = 3; i <= n; i++) {
        [res1, res2] = [res2, res1 + res2]
    }
    return res2
}

四、尾调用

尾调用之因此与其余调用不一样,就在于它的特殊的调用位置。es6

咱们知道,函数调用会在内存造成一个“调用记录”,又称“调用帧”(call frame),保存调用位置和内部变量等信息。若是在函数A的内部调用函数B,那么在A的调用帧上方,还会造成一个B的调用帧。等到B运行结束,将结果返回到AB的调用帧才会消失。若是函数B内部还调用函数C,那就还有一个C的调用帧,以此类推。全部的调用帧,就造成一个“调用栈”(call stack)。数组

尾调用因为是函数的最后一步操做,因此不须要保留外层函数的调用帧,由于调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用帧,取代外层函数的调用帧就能够了。闭包

详情参阅函数扩展之尾调用优化——阮一峰函数

function Fibonacci(n, res1 = 1, res2 = 1) {
    if (n <= 2) {
        return res2
    }
    return Fibonacci(n-1, res2, res1 + res2)
}

五、矩阵相乘-解决线性递推式问题

参考:
https://www.cnblogs.com/zkfop...
https://www.cnblogs.com/super...
https://blog.csdn.net/qq_3930...优化

相关文章
相关标签/搜索