JS寫斐波那契數列的幾種方法


  斐波那契數,指的是這樣一個數列:1、1、2、3、5、8、13、21、……在數學上,斐波那契數列以如下被以遞歸的方法定義:F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*),用文字來說,就是斐波那契數列由 0 和 1 開始,之后的斐波那契數列系數就由之前的兩數相加。  

  常用的計算斐波那契數列的方法分為兩大類:遞歸和循環。

遞歸

方法一:普通遞歸

  代碼優美邏輯清晰。但是有重復計算的問題,如:當n為5的時候要計算fibonacci(4) + fibonacci(3),當n為4的要計算fibonacci(3) + fibonacci(2) ,這時fibonacci(3)就是重復計算了。運行 fibonacci(50) 會出現瀏覽器假死現象,畢竟遞歸需要堆棧,數字過大內存不夠。

function fibonacci(n) {
    if (n == 1 || n == 2) {
        return 1
    };
    return fibonacci(n - 2) + fibonacci(n - 1);
}
fibonacci(30)

方法二:改進遞歸-把前兩位數字做成參數避免重復計算

function fibonacci(n) {
    function fib(n, v1, v2) {
        if (n == 1)
            return v1;
        if (n == 2)
            return v2;
        else
            return fib(n - 1, v2, v1 + v2)
    }
    return fib(n, 1, 1)
}
fibonacci(30)

 

 

 方法三:改進遞歸-利用閉包特性把運算結果存儲在數組里,避免重復計算

var fibonacci = function () {
    let memo = [0, 1];
    let fib = function (n) {
        if (memo[n] == undefined) {
            memo[n] = fib(n - 2) + fib(n - 1)
        }
        return memo[n]
    }
    return fib;
}()
fibonacci(30)

方法三1:改進遞歸-摘出存儲計算結果的功能函數

var memoizer = function (func) {
    let memo = [];
    return function (n) {
        if (memo[n] == undefined) {
            memo[n] = func(n)
        }
        return memo[n]
    }
};
var fibonacci=memoizer(function(n){
    if (n == 1 || n == 2) {
        return 1
    };
    return fibonacci(n - 2) + fibonacci(n - 1);
})
fibonacci(30)

循環

方法一:普通for循環

function fibonacci(n) {
    var n1 = 1, n2 = 1, sum;
    for (let i = 2; i < n; i++) {
        sum = n1 + n2
        n1 = n2
        n2 = sum
    }
    return sum
}
fibonacci(30)

方法二:for循環+解構賦值

var fibonacci = function (n) {
    let n1 = 1; n2 = 1;
    for (let i = 2; i < n; i++) {
        [n1, n2] = [n2, n1 + n2]
    }
    return n2
}
fibonacci(30)

各種方法運行耗時如下圖:普通遞歸>改進遞歸>for循環

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM