斐波那契数列(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),只使用了常数空间。
总结
- 递归法简单直观,但性能较差,适合小范围的计算。
- 动态规划法通过存储子问题的解,有效避免了重复计算,性能优良,适合中等范围的计算。
- 空间优化方法通过两个变量代替数组,进一步优化空间,适合大范围的计算。
- 矩阵快速幂方法是数学上最优的解法,适合极大范围的计算。
根据实际需求,可以选择合适的实现方法。