for( int bound = 1; bound <= n; bound *= 2 ) {
for( int i = 0; i < bound; i++ ) {
for( int j = 0; j < n; j += 2 ) {
... // constant number of operations
}
for( int j = 1; j < n; j *= 2 ) {
... // constant number of operations
}
}
}
正确的答案是O(n2)。据我所知,在前两个for循环中,它们是“嵌套的”。由于绑定从1到n,我开始绑定。第三个和第四个循环不是嵌套的。
第三个for循环具有复杂度O(n + 2),第四个for循环具有复杂度O(log n)
有人告诉我,因为n2&gt; n + 2 + log n,算法为O(n2)。 (我对这一步感到困惑)
我认为你想要将每个循环相乘,所以不应该是log n(外循环)* n(第二外循环)* n(第三)* log N(第四)。我怎么知道我需要添加或乘法的循环,以及我应该采用哪个循环的值(对于前两个循环,我是否采用N超过log N,因为N要小于处理?
答案 0 :(得分:1)
复杂性应为O(n3)
。
首先考虑最内层循环:
for( int j = 0; j < n; j += 2 ) {
... // constant number of operations
}
索引j
的值0, 2, 4, 6, 8, ...
最多为n
,因此j
最多可能需要n / 2 + 1
个值,因此此循环的复杂性为{ {1}}。
另一个最内圈:
O(n)
索引for( int j = 1; j < n; j *= 2 ) {
... // constant number of operations
}
的值j
最多为1, 2, 4, 8, 16, ...
,因此n
最多可能需要j
个值,因此此循环的复杂性为{ {1}}。
因此,对于任何已修复 log(n) + 1
和O(log(n))
,两个最内层循环完成的总工作为bound
。
现在考虑两个最外层循环。请注意,如果最外层循环的变量i
为O(n) + O(log(n)) = O(n)
,那么bound
索引的循环将完全循环k
次。
i
由于k
取值for( int bound = 1; bound <= n; bound *= 2 ) {
for( int i = 0; i < bound; i++ ) {
// work done by the inner-most loops
}
}
,因此这两个嵌套循环将循环:
bound
请注意,这只是一个geometric series,其公用比率为1, 2, 4, 8, ...
,因此求和总结为:
1^2 + 2^2 + 4^2 + 8^2 + ... + (2^⌊log(n)⌋)^2
由于最内层循环的工作与这两个循环无关,因此总复杂度由4
给出。