计算二项式系数的递归算法的时间复杂度

时间:2014-10-07 04:05:39

标签: c++ recursion complexity-theory time-complexity

我正在研究算法复杂性分析。我有不整合的问题或C(n, k)

int C(int n, int k){
   if(n==k || k==0)
     return 1;
   return C(n-1, k) + C(n-1, k-1);
}

如何确定其执行复杂性或T(n)

1 个答案:

答案 0 :(得分:9)

您正在寻找的复发是

  

T(n,k)= T(n-1,k)+ T(n-1,k-1)+ O(1),其中T(n,n)= T(n,0)= O (1)

显然,每一步减少一个n。如果我们忽略(只是暂时)存在参数k,基本上每个步骤的调用次数加倍。这种情况发生了n次,直到n = 1.现在C(1,k)返回1.因此,您最多调用C(n,k)2 n 次。所以C(n,k)在O(2 n )中。

现在我们记住了k。什么是k的最坏情况?也许k = n / 2(对于偶数n)。你可以看到你需要至少n / 2步,直到k达到1或n在任何递归调用中达到n / 2。因此,呼叫次数增加了至少2次 n / 2 次。但是还有更多的电话。写下来是相当多的工作。

修改1 所以让我们来看看这张图片

pascal's triangle with number of calls and arrows

你开始调用C(n,n / 2)(n = 6)。灰色三角形是包含在n / 2“步”中的部分,直到到达角落(C(n,0)或C(n,n))第一个。但正如你所看到的,还有更多的电话。我标记了调用,其中递归停止了一个蓝色框并写了一个特殊的C(n,k)被调用,带有绿色数字。

编辑2 C(n,k)的值和返回值1的C(n,k)的调用次数是相同的,因为该函数仅返回值1(或递归调用的结果)。 在示例中,您会看到蓝色框中写入的绿色数字的总和(即调用次数)总计为20,这也是C(6,3)的值。

编辑3 由于一个C(n,k)调用中的所有操作都在O(1)中运行(常量时间),因此我们只需计算调用以获得复杂性。注意:如果C(n,k)包含在O(n)中运行的操作,我们必须将调用次数乘以O(n)以获得复杂性。

您还会注意到与Pascal's triangle的连接。

一个小技巧

算法C(n,k)通过加1来计算Binomial coefficient。通过使用Stirling's approximation,您可以看到,C(n,n / 2)≈2 n / sqrt(n)(为简化省略了一些常量)。 因此算法必须添加许多1,因此它的复杂度为O(2 n / sqrt(n))。