解释这个Big O复杂性代码的答案

时间:2014-11-18 02:19:32

标签: big-o

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要小于处理?

1 个答案:

答案 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) + 1O(log(n)),两个最内层循环完成的总工作为bound


现在考虑两个最外层循环。请注意,如果最外层循环的变量iO(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给出。