線性遞推式問題-斐波那契數列

一、遞歸

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...優化

相關文章
相關標籤/搜索