这不是javascript的错,而是你的算法。你一遍又一遍地重新计算相同的子问题,当 N 更大时它会变得更糟。这是单个调用的调用图:
F(32)
/ \
F(31) F(30)
/ \ / \
F(30) F(29) F(29) F(28)
/ \ / \ / \ | \
F(29) F(28) F(28) F(27) F(28) F(27) F(27) F(26)
... deeper and deeper
正如您从这棵树中看到的,您正在多次计算一些斐波那契数,例如 F(28) 被计算了 4 次。来自“算法设计手册”一书:
这个算法需要多少时间来计算 F(n)?由于 F(n+1) /F(n) ≈ φ = (1 + sqrt(5))/2 ≈ 1.61803,这意味着 F(n) > 1.6^n 。由于我们的递归树只有 0 和 1 作为叶子,加起来这么大的数字意味着我们必须至少有 1.6^n 个叶子或过程调用!这个不起眼的小程序需要指数级的时间来运行!
您必须使用记忆或自下而上构建解决方案(即首先是小子问题)。
此解决方案使用记忆化(因此,我们只计算每个斐波那契数一次):
var cache = {};
function fib(n) {
if (!cache[n]) {
cache[n] = (n < 2) ? n : fib(n - 1) + fib(n - 2);
}
return cache[n];
}
这个自下而上解决它:
function fib(n) {
if (n < 2) return n;
var a = 0, b = 1;
while (--n) {
var t = a + b;
a = b;
b = t;
}
return b;
}