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

时间:2018-07-29 02:24:42

标签: 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(int n ){
    if(n <= 0) return 0;
    else if (n == 1) return 1;
    return fib(n-1) + fib(n-2);
}

3 个答案:

答案 0 :(得分:1)

我终于从教授那里得到了答案,并将其发布在这里:

根据他的说法:您不仅应该简单地查看从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)。

答案 1 :(得分:1)

我已经想出了自己的方式来理解这本书的解决方案,希望它能对仍在挣扎中的人们有所帮助。

想象一下,我们现在称为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)。 *

按照sum of powers of 2 formula进行操作,

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

因此它是O(2 ^ n)

答案 2 :(得分:0)

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

我们知道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。