斐波那契数列(Fibonacci Sequence)

211 阅读3分钟

斐波那契数列(Fibonacci Sequence)是一个经典的数学数列,其定义如下:

  • 第 0 项是 0:F(0) = 0
  • 第 1 项是 1:F(1) = 1
  • 从第 2 项开始,每一项是前两项之和:F(n) = F(n-1) + F(n-2),其中 n ≥ 2。

具体的数列如下:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

使用 JavaScript 实现斐波那契数列

方法 1:递归法

递归法直接按照斐波那契数列的定义进行计算:

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

console.log(fibonacci(10)); // 输出 55

时间复杂度:O(2^n),因为存在重复计算。
空间复杂度:O(n),递归调用栈的深度。

方法 2:动态规划(自底向上)

为了避免递归法中的重复计算,可以使用动态规划的方式。动态规划从最基础的值开始,逐步计算更大的斐波那契数值。

function fibonacci(n) {
    if (n <= 1) return n;
    
    let dp = [0, 1];  // 初始化前两项
    for (let i = 2; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    
    return dp[n];
}

console.log(fibonacci(10)); // 输出 55

时间复杂度:O(n),只需遍历一次。
空间复杂度:O(n),需要一个数组存储结果。

方法 3:空间优化(只用两个变量)

因为计算第 n 个斐波那契数值只需要前两项的值,因此可以进一步优化空间复杂度,使用两个变量来保存前两项的值。

function fibonacci(n) {
    if (n <= 1) return n;
    
    let a = 0, b = 1;
    for (let i = 2; i <= n; i++) {
        let temp = a + b;
        a = b;
        b = temp;
    }
    
    return b;
}

console.log(fibonacci(10)); // 输出 55

时间复杂度:O(n),只需遍历一次。
空间复杂度:O(1),只用了常数空间。

方法 4:矩阵快速幂(高级优化)

对于斐波那契数列,还可以使用矩阵快速幂的方法来求解,时间复杂度为 O(log n)。

function matrixMultiply(a, b) {
    return [
        [a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]],
        [a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]]
    ];
}

function matrixPower(matrix, n) {
    let result = [[1, 0], [0, 1]]; // 单位矩阵
    let base = matrix;

    while (n > 0) {
        if (n % 2 === 1) {
            result = matrixMultiply(result, base);
        }
        base = matrixMultiply(base, base);
        n = Math.floor(n / 2);
    }

    return result;
}

function fibonacci(n) {
    if (n <= 1) return n;

    const matrix = [[1, 1], [1, 0]];
    const result = matrixPower(matrix, n - 1);

    return result[0][0];
}

console.log(fibonacci(10)); // 输出 55

时间复杂度:O(log n),通过矩阵快速幂加速计算。
空间复杂度:O(1),只使用了常数空间。

总结

  • 递归法简单直观,但性能较差,适合小范围的计算。
  • 动态规划法通过存储子问题的解,有效避免了重复计算,性能优良,适合中等范围的计算。
  • 空间优化方法通过两个变量代替数组,进一步优化空间,适合大范围的计算。
  • 矩阵快速幂方法是数学上最优的解法,适合极大范围的计算。

根据实际需求,可以选择合适的实现方法。