指数时间复杂度

时间:2014-02-20 15:20:07

标签: algorithm time-complexity fibonacci

Fibonacci的时间复杂度为O(2 ^ n) 如果我想获得3 ^ n的时间复杂度怎么办?

据我的朋友说,由于以下步骤,斐波那契的时间复杂度为O(2 ^ n): -

return fibonacci(n-1)+fibonacci(n-2)

另外他说如果写的话会变成O(3 ^ n): -

return fibonacci(n-1)+fibonacci(n-2)+fibonacci(n-3)

有人可以告诉为什么会这样吗?

根据他的说法,这是因为我们在每一步都要调用两次Fibonacci函数,这就是为什么它是O(2 ^ n)。如果是这样,那么下面代码的复杂性应该是O(k ^ k),但据我所知,它是O(n)

void permute(int k,int size) {  
    // some base case    
    for (i=k-1;i>=0;i--)          
    permute(k-1,size);  
    return; 
}

他的逻辑对我来说似乎很垃圾。对我而言,由于合并成本,它是2 ^ n。 二进制树遍历的成本与O(n)相同,尽管函数在每一步都调用两次。

有人可以告诉我,我们中间谁错了,实际的逻辑是什么?

2 个答案:

答案 0 :(得分:3)

这个previous answer应该说服斐波纳契的序列算法时间复杂度。

然后,基于相同的答案原则,您的新序列算法可以表示为

T(n) 
= T(n-1) + T(n-2) + T(n-3) 
= ( T(n-2)+T(n-3)+T(n-4) )+( T(n-3)+T(n-4)+T(n-5) )+( T(n-4)+T(n-5)+T(n-6) )
= ...

您会看到每个节点创建3个新节点。该算法复杂度变为O(3 ^ n)

来自Wolfram的图片:(考虑节点13到37在下面继续,因为树的底部不是“平坦的”,因为第一级“n-3”节点将在“n-2”之前完成,在“n-1”等之前完成......)

enter image description here

答案 1 :(得分:3)

实际上O(2 ^ n)有点超出它(但仍然正确,因为big-O是上限),it's more like ~θ(1.6^n)

尝试描绘递归树。每个节点都分成2个,树的深度为n,所以最终大约为O(2 ^ n)。

类似地,O(3 ^ n)示例,每个节点分裂为3,深度仍为n。

但是对于O(3 ^ n),我宁愿推荐这样的东西:

someFunction(n)
  if (n == 0)
    return 1
  return someFunction(n-1) + someFunction(n-1) + someFunction(n-1)

当然,通过将最后一个return语句更改为:

,这可以简单地转换为O(n)
return 3*someFunction(n-1)

但这不是重点(人们还可以计算O(n)中的第n个斐波纳契数。)

现在很容易评估。

n有1个调用,n-1有3个,n-2,3 * 3个,n-3有3 * 3 * 3个等。

通常,运行时间为O(3 ^ n)。


对于permute函数:

由于您将k-1传递给递归通话(不是i),因此您需要1呼叫k,k-1呼叫k-1,{{1对于k-2,(k-1)(k-2)表示k-3,等等。

所以看起来像(k-1)(k-2)(k-3)


如果您要通过O((k-1)!),则i要求k,1要求k-1,1要求k-2,{{ 1}}表示k-3,1+1=2表示k-4,1+1+2=4表示k-5等。

所以看起来像1+1+2+4=8


二叉树遍历需要16,但O(2^(k-1))不是二叉树的高度,而是节点的数量。在Fibonacci示例中,O(n)是高度。如果我们考虑根据高度遍历平衡二叉树需要多长时间,我们最终得到n,从一些基本数学开始,最终为n