关于代码的大O的解释

时间:2014-03-08 02:49:40

标签: algorithm discrete-mathematics

我需要一些帮助来理解代码上的Big O概念。我们只讨论了30分钟,我们没有讨论如何解释java上的代码(我认为?)。任何人,我会尝试尝试我的解决方案,你们可以告诉我,如果我是对或错,并给我一个正确的解释?

谢谢你!

 sum = 0 ;
    for ( i = 0 ; i < n ; i++ ) --> n
        for ( j = 1 ; j < n^3 ; j = 3*j ) --> n*(3n^3) (WRONG) --> log(n)
            sum++ ;
因此,这个上的大O是O(n ^ 4)(错) 正确答案= O(nlog(n))

sum = 0 ;
for ( i = n ; i > 0; i = i/3 ) --> n^(1/3) (WRONG) --> log(n)
    for ( j = 0 ; j < n^3 ; j++ )--> n^(1/3) * (n^3)
       sum++ ;

因此,这个上的大O是O(n)(错) 正确答案= O(n ^ 3log(n))

2 个答案:

答案 0 :(得分:1)

第一个例子:

sum = 0 ;
for ( i = 0 ; i < n ; i++ ) --> n
   for ( j = 1 ; j < n^3 ; j = 3*j ) --> O(log n)
        sum++ ;

第二个循环将是logn,因为我们每次将j乘以因子3,因此顺序将是O(n logn)而不是n ^ 4

每个循环的Big O计算是正确的,但是,如果循环中有循环,则将计算相乘。

sum = 0 ;
for ( i = n ; i > 0; i = i/3 ) --> log n
    for ( j = 0 ; j < n^3 ; j++ )--> n^3
       sum++ ;

这里的第一个循环也将是log n,因为你经常除以3,所以乘以我们得到的2个循环的顺序:

O(logn * n^3) = O(n^3 logn)

我们无法进一步减少,因为我们没有要删除的常量。

只是指出一个我们可以对这种情况有一个简单的误解,通常如果我们有以下情况,我们可以像

那样减少它。
O(n^3 + n^2) = O(n3)

但是,您的方案不是添加订单,而是增加,所以我们再次无法删除此处的O(logn)

如何分析代码:

我是这样做的,让我们举个例子

for(i=0; i < n; i++)
    for(j=0; j < n*2; j++)
for(k=0; k<n; k++)
    for(l=0; l<n; l+=3)
        for(m=0; m<n; m*=2)

首先,找到每个循环的大0:

for(i=0; i < n; i++)        --> O(n)
    for(j=0; j < n*2; j++)  --> 2n = O(n)
for(k=0; k<n; k++)          --> O(n)
    for(l=0; l<n; l+=3)     --> n/3 = O(n)
        for(m=0; m<n; m*=2)  --> O(log n)

将外循环乘以它们的内循环:

for(i=0; i < n; i++)        --> O(n) * O(n) = O(n^2)
    for(j=0; j < n*2; j++)  --> 2n = O(n)
for(k=0; k<n; k++)          --> O(n) * O(n) * (log n) = O(n^2 (log n))
    for(l=0; l<n; l+=3)     --> n/3 = O(n)
        for(m=0; m<n; m*=2)  --> O(log n)

现在我们添加外循环的顺序,所以我们得到:

O(n^2) + O(n^2 log n) = O(n^2 + n^2 (logn))

然后我们减少订单。在这种情况下,n ^ 2 log n的生长速率大于n ^ 2,因此我们可以删除n ^ 2,因为n ^ 2 logn足以解释增长率。最后,我们有:

O(n^2 (log n))

答案 1 :(得分:0)

在第一个代码块中,第一个for循环正确,但第二个for循环没有。在第二个for循环中,j呈指数增长,即j = 1,3,9,27 ...
因此,时间以最终值的对数增加。让我们看一个基于这行代码的例子

for ( j = 1; j < m; j = 3*j )

这是m,j和时间值的表格

m     j        time
1     -         0       // body of loop never executes   
3     1         1       // body of loop executes one time  
9     1,3       2     
27    1,3,9     3  
81    1,3,9,27  4  

所以在这种情况下,时间是log_base_3( m ),在bigO表示法中只是O(log m)。如果用n ^ 3替换m,则时间为3 * log_base_3( n ),实际上只是O(log n),因为bigO忽略常量乘数。底线,第一个块的解决方案是O(n * log(n))

可以用类似的方式分析另一个块。