这段代码的Big-O复杂性是什么?

时间:2015-05-16 01:53:14

标签: big-o time-complexity

什么是

的大O.
void fun(int n) {
   for(i=1; i<=n; i=i+2) { }
}

我的回答:O(log n)(因为i值是1,3,5,7,9总共减少了2)

void fun(int n) {
    for(i=1; i<=n; i=i+2) { }
}

我的回答:O(log n),因为这是二次方(我认为)。

void fun (int n) {
    for (i=1; i<=n; i++) {
        for(j=1;j<=n;j++) { }

        for(k=1;k<=n;k++) { }
     }
}

我的回答:O(n ^ 3)因为循环必须在j内专门用于ki

请澄清。

4 个答案:

答案 0 :(得分:3)

big-O表示法的正式定义是

  

f(x)∈O(g(x)),因为存在c> 0(例如,c = 1)和x0(例如,x0 =   5)使得f(x)<1。 cg(x)每当x&gt; X0。

从你的想法来看,似乎你不明白如果有一个常数可以乘以g(x)使得f(x)总是小于或等于g(x),f(x )不是比g(x)更大的数量级。

以下是大O解决方案:

(1)O(n)。 O(n / 2)是O(n)

(2)O(n)因为这与(1)

相同

(3)O(n ^ 2)因为内环在外环的每次迭代中运行2 * n次,运行n次。因此,运行是2 * n * n,其为O(n ^ 2)

答案 1 :(得分:3)

  1. O(n):即使将处理的值的数量增加两半,它仍然 n 成比例。比较这些n,n / 2和log n:

    的图表

    你可以看到n / 2与n成正比(总是正好是一半,即它被常数因子关闭),而log n显着增加得更慢。

    在big-O表示法中,常数因子被忽略,即O(2n)= O(n),因为当n非常大时,2与n相比无关紧要。

    < / LI>
  2. 假设您在第二个示例中可能意味着for(i=1;i<=n; i=i*2 ),实际上这将是O(log n),因为您正在检查指数增加的值(1,2,4,8,16 ......),因此i在达到 n 之前最多会加倍 log n 次EM>。例如,如果n = 16,i将加倍4倍(如上面列出的例子), 4 = log 2 16

  3. O(n²)因为内循环运行2次,外循环运行n次,所以每次内循环迭代都是O(n),所以当运行时 n 外环的时间,总复杂度为O(n²)。

  4. 通常,快速估算代码时间复杂度的方法,如果你有许多嵌套循环,每个循环从0到n(可能有一些常数因子),就是计算循环嵌套的深度。然后,假设每个最内层循环迭代执行常量时间操作(例如,递增数字,访问数组索引),总时间复杂度将为 n ^ k ,其中 k 是嵌套循环的数量。这适用于您的示例3,它具有2级循环嵌套(即使最内层有一个接一个的循环,这只是添加一个常量因子)。

答案 2 :(得分:1)

第一个是O(n)。是的,你跳过了一半的循环周期,但这意味着对于每一个n,你循环n / 2次,O(n / 2)与O(n)相同。

第二个看起来就像第一个,但我会假设你的意思:

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

}

是的,那是O(log n)

第三个可能会让你感到困惑,因为它给人的印象是一个三重嵌套循环,但事实并非如此,两个内部循环嵌套在第一个循环上,所以它真的是O(n *(n + n)) = O(n * 2n)= O(2n ^ 2),最终为O(n ^ 2)

答案 3 :(得分:0)

void fun(int n){
    for(i=1;i<=n;i=i+2){;}
}

示例循环:

i:    1   3   5   7   9   11   13   15   ...
  

循环迭代大约n / 2次,即O(n)。

void fun(int n){
    for(i=1;i<=n;i=i*2){;}
}

示例循环将通过:

i:    1   2   4   8   16   32   64   128   ...
  

这不是二次方的。这是指数级的。它循环   大约log(n)次(到2的基数,但它不是真的   在这里),因此它在O(log(n))。

二次(2次多项式)将是

i:    1   4   9   16  25   36  49  64  ... 

尝试看看这两者之间的差异,指数开始变慢,但是越长越快,增长越快。

void fun(int n){
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){;} // O(n)
        for(k=1;k<=n;k++){;} // O(n)
    }
}

两个内部循环分别执行n次,即2 * n步。

  

外循环执行n次。在每一步中,两个内环   执行。总共得到n * 2 * n,即O(n ^ 2)。