【问题标题】:Time-complexity of recursive algorithm for calculating binomial coefficient计算二项式系数的递归算法的时间复杂度
【发布时间】:2014-12-01 10:19:31
【问题描述】:

我正在研究算法复杂性分析。我有不符合的问题或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步:写一个重复。
  • 对不起,我不明白,你能不能说清楚一点
  • 我的意思是,为 T(n, k) 编写方程,使得 T(n, k) 是 C(n, k) 运行时间的大 Theta。
  • 我认为 T(n) 是:if(n==
  • 我想你的意思是if(n==k || k==0)0 不见了。

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


【解决方案1】:

你要找的重复是

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) 2n 次。所以 C(n,k) 在 O(2n) 中。

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

编辑 1 那么让我们来看看这张照片

您开始调用 C(n,n/2)(n=6)。灰色三角形是包含在 n/2 个“步骤”中的部分,直到您到达拐角(C(n,0) 或 C(n,n))first。但是正如你所看到的,还有更多的调用。我标记了调用,其中递归以蓝色框停止,并用绿色数字写下了调用特殊 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) ≈ 2n/sqrt(n) (为了简化省略了一些常量)。 所以算法必须添加那么多的 1,所以它的复杂度为 O(2n/sqrt(n))。

【讨论】:

  • 直到“至少需要 n/2 步直到 k 达到 1 或 n 达到 n/2”我才明白,但我认为,在 n/2 步(最多)之后,k 必须达到 1 或n 远达到 k,所以最大步数必须是 n/2(而不是至少 n/2)?你能告诉我更清楚吗? 1 是 1 步吗?为什么我们有 C(n, n/2) 的复杂度?
  • @HyNguyen 我稍微改进了我的答案。
  • 我花了一些时间来消化它 :) 那么为什么我们通过 C(n, n/2) 计算 C(n, k) 的复杂度,它是最大复杂度吗?
  • 是的,C(n,n/2) 是最坏的情况。在复杂性理论和特别是大 O 中,您对最坏情况的复杂性感兴趣。由于 C(n,k) 是对称的,因此 C(n,n/2) 是最坏的情况。
  • @PanosK。我使用了 Illustrator。
猜你喜欢
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 2011-02-12
相关资源
最近更新 更多