可以在 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),但实际时间更像是 a、b n + c 和 d n + e,a、b、c、d 和 e 的值取决于硬件、编译器、实现等。对于现代 CPU,a 很可能不会比 b 或 d[=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]
.
我问自己是否可以在 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),但实际时间更像是 a、b n + c 和 d n + e,a、b、c、d 和 e 的值取决于硬件、编译器、实现等。对于现代 CPU,a 很可能不会比 b 或 d[=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]
.