【问题标题】:How can I find Big-O notation for my loops?如何为我的循环找到 Big-O 表示法?
【发布时间】:2014-02-26 15:33:44
【问题描述】:

我在找出这段代码的 Big-O 表示法时遇到了麻烦。 我需要找到两个 for 循环的符号。

public static int fragment(int n)
{
  int sum = 0;

  for (int i = n; i >= 1; i /= 2)
  {
    for (int j = 1; j <= i; j *= 3)
    {
      sum++;
    }
  }

  return sum;
}

【问题讨论】:

  • 嗯...我倾向于说它是O(n log n)...外循环是log n,内循环是n...
  • @NiettheDarkAbsol 一点也不。内循环是log(i)
  • @IvayloStrandjev 怎么样?如果有的话,就是i/3,就是i……如果ilog n,那么……呃……我不知道XD
  • 啊,我快到了!我在想“如果ilog n 那么结果就是(log n)^2”,但我想我会说些傻话XD

标签: big-o complexity-theory time-complexity


【解决方案1】:

分别考虑两个循环:

首先让我们考虑for(int i=n; i&gt;=1; i/=2) 在每次迭代中,i 的值将除以 2,直到它达到小于 1 的值。因此,迭代次数 N 将等于您应该将 i 除以 2 在它小于 1 之前的次数。有一个众所周知的函数表示这个数字 - log(n)

现在让我们考虑内部循环。 for(int j=1;j&lt;=i; j*=3)。在这里,您将 j 乘以 3,直到它超过 i。如果您稍微考虑一下,这与以下对第一个循环的轻微修改所执行的迭代次数完全相同:for(int j=i; j&gt;=1; j/=3)。并且通过完全相同的解释,我们具有相同的功能(但具有不同的基数 - 3)。这里的问题是迭代次数取决于 i。

所以现在我们的总复杂度是:

log3(n) + log3(n/2) + log3(n/4) ... + log 3(1) =

log3(n) + log3(n) - log3(2) + log3(n) .... - log3(2log2(n)) =

log3(n) * log2 (n) - log3(2) - 2 * log3(2) - ... log2(n) * log3(2) =

log3(n) * log2 (n) - log3(2) * (1 + 2 + ...日志2) =

log3(n) * log2 (n) - log3(2) * (log2 sub>(n) * (log2(n) + 1)) / 2 =

log2 (n) * (log3(n) - log3(2) * (log2(n) + 1) / 2) =

log2 (n) * (log3(n) - (log3(n) + log3(2)) / 2) =

(log2 (n) * log3(n)) / 2 - (log2 (n) * log3(2)) / 2

计算有点棘手,我使用了一些对数属性。然而,最终的结论是循环具有复杂性O(log(n)^2)(请记住,您可以忽略对数的底数)。

【讨论】:

    【解决方案2】:

    为了正式推断时间复杂度,使用 sigma 表示法是一种合适的方法:

    WolframAlpha 帮助我对封闭式公式求和。

    对于对数,您可以查看this document 的最后一张幻灯片,Jauhar 博士解释了对数循环。

    【讨论】:

    • 其实这是Omega(log(n)^2)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2012-03-02
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    相关资源
    最近更新 更多