3个循环的Hard Big O复杂度

时间:2018-08-20 20:12:10

标签: time-complexity big-o complexity-theory nested-loops code-analysis

我尝试为此代码计算Big O复杂度,但是我总是失败。...

我试图嵌套SUM或获取每种情况下的步骤数,例如:

  • i = 1 j = 1 k = 1(1步)
  • i = 2 j = 1,2 k = 1,2,3,4(4步)
  • 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。
  • i = n(我说n = 2 ^(log n)j = 1,2,4,8,16,.....,nk = 1,2,3,4,.... n ^ 2(n ^ 2步)

然后将所有步骤汇总在一起,我需要帮助。

for (int i=1; i<=n; i*=2)

   for (int j=1; j<=i; j*=2)

      for(int k=1; k<=j*j; k++)

           //code line with complexity code O(1)

2 个答案:

答案 0 :(得分:2)

For the outermost loop:

  sum_{i in {1, 2, 4, 8, 16, ...}} 1, i <= n (+)

  <=>

  sum_{i in {2^0, 2^1, 2^2, ... }} 1, i <= n

Let 2^I = i:

  2^I = i <=> e^{I log 2} = i <=> I log 2 = log i <=> I = (log i)/(log 2)

Thus, (+) is equivalent to

  sum_{I in {0, 1, ... }} 1, I <= floor((log n)/(log 2)) ~= log n                      (*)

Second outermost loop:

  sum_{j in {1, 2, 4, 8, 16, ...}} 1, j <= i (++)

As above, 2^I = i, and let 2^J = j. Similarly to above,
(++) is equivalent to:

  sum_{J in {0, 1, ... }} 1, J <= floor((log (2^I))/(log 2)) = floor(I/(log 2)) ~= I   (**)

To touch base, only the outermost and second outermost
have now been reduced to

  sum_{I in {0, 1, ... }}^{log n} sum_{J in {0, 1, ...}}^{I} ...

Which is (if there would be no innermost loop) O((log n)^2)

Innermost loop is a trivial one if we can express the largest bound in terms of `n`.

  sum_{k in {1, 2, 3, 4, ...}} 1, k <= j^2 (+)

As above, let 2^J = j and note that j^2 = 2^(2J)

  sum_{k in {1, 2, 3, 4, ...}} 1, k <= 2^(2J)

Thus, k is bounded by 2^(2 max(J)) = 2^(2 max(I)) = 2^(2 log(n) ) = 2n^2                (***)

结合(*)(**)(***),三个嵌套循环的渐近复杂度为:

  • O(n^2 log^2 n)(或O((n log n)^2))。

答案 1 :(得分:2)

让我们看一下内部循环运行的次数:j2。但是j以2的幂逐步增加到ii依次以2的幂递增至n。因此,让我们“绘制”一些总和项的图形,这将为我们提供迭代的总数:

  ---- 1
   ^   1 4
   |   1 4 16
log2(n)   ...
   |   1 4 16 ... n2/16
   v   1 4 16 ... n2/16 n2/4
  ---- 1 4 16 ... n2/16 n2/4 n2
       |<------log2(n)------>|

该图形可以解释如下:i的每个值对应于一行。 j的每个值都是该行中的一列。数字本身就是k经历的迭代次数。 j的值是数字的平方根。 i的值是每一行中最后一个元素的平方根。所有数字的总和就是迭代的总数。

从最底行开始,总和的项为(2z)2 = 22z的{​​{1}}。项在总和中出现的次数由列的高度调整。给定术语的高度为z = 1 ... log2(n)(基本上是log2(n) + 1 - z的倒数)。

所以最终的总和是

log2(n)
  Σ  22z(log2(n) + 1 - z)
 z = 1

Wolfram Alpha在评估总和时要说的是:http://m.wolframalpha.com/input/?i=sum+%28%28log%5B2%2C+n%5D%29+%2B+1+-+z%29%282%5E%282z%29%29%2C+z%3D1+to+log%5B2%2C+n%5D

C1n2 - C2log(n) - C3

切出所有次要的项和常数,结果是

O(n2)