可以在 O(n) 或 O(1) 时间内计算出第 n 个斐波那契数吗?为什么?

Can one compute the nth Fibonacci number in time O(n) or O(1)? Why?

我问自己是否可以在 O(n) 或 O(1) 时间内计算第 n 个斐波那契数,为什么?

有人可以解释一下吗?

与其考虑递归方法,不如考虑自下而上构建序列,从 1+1 开始。

是的。它被称为Binet's Formula, or sometimes, incorrectly, De Moivre's Formula (the real De Moivre's formula is another,但De Moivre确实比奈先于比奈发现了比奈公式),并且涉及到黄金比例Phi。这背后的数学推理(参见link)有点复杂,但可行:

虽然它是一个近似公式,但斐波那契数是整数——所以,一旦你达到足够高的精度(取决于 n),你可以从比奈公式求最接近的整数。

但是精度取决于常量,所以你基本上有两个版本,一个是浮点数,一个是双精度数,第二个也是 运行 常数时间,但速度稍慢。对于 large n,您将需要一个 任意精度数字库 ,并且这些库的处理时间确实取决于所涉及的数字;正如@MattTimmermans 所观察到的,您最终可能会得到一个 O(log^2 n) 算法。如果 n 的值足够大,那么无论如何您都会被 large-number 库困住(但我需要对此进行测试以确保)。

另外,比奈公式主要是两次求幂和一次除法(三个和和除以2大概可以忽略不计),而递归公式主要是函数调用,迭代公式是用循环。虽然第一个公式是 O(1),另外两个是 O(n),但实际时间更像是 ab n + cd n + e,a、b、c、d 和 e 的值取决于硬件、编译器、实现等。对于现代 CPU,a 很可能不会比 bd[=37 大太多=],这意味着 O(1) 公式对于几乎每个 n 应该更快。但是大多数迭代算法的实现都是从

开始的
if (n < 2) {
        return n;
}

对于 n = 0 和 n = 1,这很可能更快。我相信 Binet 的公式对于超过个位数的任何 n 都更快。

您也可以像这样使用矩阵 m

1    1
1    0

并计算它的n次方。然后输出 m^n[0,0].