我尝试为此代码计算Big O复杂度,但是我总是失败。...
我试图嵌套SUM或获取每种情况下的步骤数,例如:
然后将所有步骤汇总在一起,我需要帮助。
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)
答案 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的幂逐步增加到i
。 i
依次以2的幂递增至n
。因此,让我们“绘制”一些总和项的图形,这将为我们提供迭代的总数:
---- 1 ^ 1 4 | 1 4 16log2(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)