Time complexity 从0到n的所有斐波那契数的时间复杂度

Time complexity 从0到n的所有斐波那契数的时间复杂度,time-complexity,fibonacci,Time Complexity,Fibonacci,我在计算这段代码的时间复杂度,这段代码打印从0到n的所有斐波那契数。根据我的计算,fib()方法需要O(2^n)并且因为它被调用了I次,所以结果是O(n*2^n)。然而,这本书说它是O(2^n)。谁能解释一下为什么这里的时间复杂度是O(2^n) 代码如下: void allFib(int n){ for(int i = 0 ; i < n ; i++){ System.out.println(i + ": " + fib(i)); } } int fib(

我在计算这段代码的时间复杂度,这段代码打印从0到n的所有斐波那契数。根据我的计算,
fib()
方法需要
O(2^n)
并且因为它被调用了
I
次,所以结果是
O(n*2^n)
。然而,这本书说它是
O(2^n)
。谁能解释一下为什么这里的时间复杂度是O(2^n)

代码如下:

void allFib(int n){
    for(int i = 0 ; i < n ; i++){
        System.out.println(i + ": " + fib(i));
    }
}

int fib(int n ){
    if(n <= 0) return 0;
    else if (n == 1) return 1;
    return fib(n-1) + fib(n-2);
}
void allFib(int n){
对于(int i=0;i如果(n我终于从我的教授那里得到了答案,我会把它贴在这里:

按照他的说法:你不应该只是简单地寻找从0到n迭代的for循环,你必须通过计算步骤找到实际的计算结果

fib(1)需要2^1个步骤

fib(2)需要2^2个步骤

fib(3)需要2^3个步骤

fib(n)需要2^n个步骤

现在添加以下内容:

2^1+2^2+2^3+2^n=2^n+1


忽略常数,它是2^n,因此时间复杂度是O(2^n)。

我认为最好的思考方法是用一个例子

我们知道fib()大约运行O(2^n)次,直观地说,我们认为allFib()的运行时是O(n*2^n),正如书中提到的。但事实并非如此,原因如下

为什么O(n*2^n)是错误的:

如果我们用3代替n,我们得到3*2^3,等于2^3+2^3+2^3。这显然是错误的,因为从代码中我们知道第一个循环运行2^1,第二个循环运行2^2,第三个循环运行2^3次。所以它应该是2^1+2^2+2^3

我们如何得到O(2^n):


如果我们说n=3,我们知道功的总和是2^1+2^2+2^3,这大约等于2^4(请看《二次幂和》一书中的630页了解原因),所以你可以说完成的工作量是2^n+1,但是我们去掉了大O的所有常数,所以剩下2^n。

我找到了自己的方法来理解这本书的解决方案,希望它能帮助那些仍在挣扎的人

假设我们现在称为allFib(n)

由于我们有一个从0到n的for循环,因此将调用以下函数:

  • i=0,调用fib(0)
  • i=1,调用fib(1)
  • i=2,调用fib(2)
  • i=n-1,调用fib(n-1)
如前所述,fib(n)将采取O(2^n)=2^n步 所以,

  • i=0,调用fib(0)需要2^0个步骤
  • i=1,调用fib(1)需要2^1个步骤
  • i=2,调用fib(2)需要2^2个步骤
  • i=n-1,调用fib(n-1)需要2^(n-1)个步骤
因此,allFib(n)的运行时将是

2^0+2^1+2^2+…+2^(n-1)。
*

按照我们的计划:

*
=2^(n-1+1)-1=2^n-1


因此它是O(2^n)

可能重复的@Am_I_有用请在标记重复之前仔细阅读问题。您提供的链接中的内容不是我问题的答案。当计算
fib(n)
时,您已经得到
fib(n-1)
fib(1)
的所有结果。因此计算
fib(n)
与计算所有这些函数的复杂度相同。但是您的
allFib
函数不同,因为它没有保存以前的
fib(n-1)
fib(n-2)
来计算
fib(n)
。因此
allFib
的时间复杂度为O(n*2^n)。@Shaunsia这就是我的答案,但书上说是O(n*2^n)这不是任何一本书,它破解了G.L.Mcdowell的编码采访。对我来说,这可能是重复的。这仅仅解释了
fib(n)
本身的时间复杂性。我确实理解它必须是
2^n
的原因。但仍然。
fib(n)
for
循环中找到。这意味着fib(n)我不明白为什么它不是书上说的那样。