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

时间:2019-06-06 14:24:45

标签: algorithm time-complexity big-o fibonacci

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

有人可以解释吗?

3 个答案:

答案 0 :(得分:4)

是的。它被称为Binet's Formula,或者有时是错误地是De Moivre的公式(真正的De Moivre公式是another,但De Moivre did 发现了Binet的公式) Binet之前的公式),并涉及黄金比例Phi。背后的数学推理(请参阅链接)有点儿涉及,但可行:

enter image description here

虽然它是一个近似公式,但斐波那契数是整数-因此,一旦达到足够高的精度(取决于 n ),就可以将Binet公式中的数字近似为最接近的数整数。

然而,精度取决于常量,因此您基本上有两个版本,一个带有浮点数,一个带有双精度数,而第二个版本也在恒定时间内运行,但速度稍慢。对于 large n,您将需要一个任意精度数字库,而这些库的处理时间确实取决于所涉及的数字。正如@MattTimmermans观察到的那样,您可能最终会得到O(log ^ 2 n)算法。对于足够大的 n 值,应该会发生这种情况,以至于无论如何您都将被大量的库卡住(但我需要对此进行测试以确保确定)。

否则,Binet公式主要由两个乘幂和一个除法组成(三个总和与2的除法可以忽略不计),而递归公式主要使用函数调用,而迭代公式使用循环。虽然第一个公式是O(1),其他两个公式是O(n),但实际时间更像 a bn + c dn + e ,其中a,b,c,d和e的值取决于硬件,编译器,实现等。对于现代CPU,很可能 a 不会比 b d 大,这意味着O(1)公式应几乎每个 n 都更快。但是迭代算法的大多数实现都是以

开头
if (n < 2) {
        return n;
}

对于n = 0和n = 1,这很有可能会更快。我有信心Binet的公式对于除个位数之外的任何n都会更快。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

1    1
1    0

并计算其幂n。然后输出m^n[0,0]