Big-O for-loop运行时分析

时间:2015-02-07 21:31:27

标签: algorithm for-loop runtime big-o

 int n = 500;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < i; j++)
            sum++;

我的猜测是这只是一个O(N ^ 2),但是j&lt;我在怀疑你。

int n = 500;
     for(int i = 0; i < n; i++)
        for(int j = 0; j < i*i; j++)
            sum++;

好像是O(N ^ 3)

  int n = 500;
     for(int i = 0; i < n; i++)
        for(int j = 0; j < i*i; j++)
            if( j % i == 0 )
               for( k = 0; k < j; k++ )
                  sum++

O(N ^ 5)?

因此,对于每个循环,j具有不同的值。如果是j&lt; n * n,它会更直接,但这个是一个棘手的,所以请帮助。谢谢。

3 个答案:

答案 0 :(得分:3)

在第一种情况下sum++执行0 + 1 + ... + n-1次。如果您应用arithmetic progression公式,则会获得n (n-1) / 2 O(n^2)

在第二种情况下,我们会0 + 1 + 4 + 9 + ... + (n-1)^2,这是第一个n-1数字的平方和,并且a formula(n-1) n (2n-1):{{1} }}

最后一个很有意思。实际上,您可以看到,只有当forj的被乘数时,才会调用最嵌套的i循环,因此您可以按如下方式重写程序:

int n = 500;
for(int i = 0; i < n; i++) {
   for(int m = 0; m < i; m++) {
       int j = m * i;
       for( k = 0; k < j; k++)
             sum++
   }
}

使用数学符号更容易:

Derivation

公式是通过分析从代码派生的:我们可以看到sum++在最内层循环中被称为j次,称为i次,称为n 1}}次。最后,问题归结为首先n个数字加上低阶项(不影响渐近)的多维数据集的总和

最后一点注意事项:它看起来很明显,但我想表明N dΩ(N^(d+1))自然数的一般总和为Θ(N^(d+1))(参见维基百科)对于Big-Omega notation),即它的增长速度不比该函数慢。您可以应用相同的推理来证明满足更强的条件,即它属于Ω,它结合了O和{{1}}。

Derivation

答案 1 :(得分:1)

除最后一个之外的所有人都是正确的,它具有更紧密的O(n^4)范围:请注意,只有当for是{{的倍数时才执行最后一个j循环1}}。 i的{​​{1}}倍数低于或等于x / ii。因此,最后一个循环仅针对x中的i * i / i = i值执行。

请注意,big-oh给出了上限,因此i vs i * i没什么区别。严格地说,他们都是i*i也是正确的(因为这是一个有效的上限),但它几乎没有帮助,所以在实践中通常使用紧束缚。

答案 2 :(得分:0)

IVlad已经给出了正确答案。

我觉得让你感到困惑的是&#34; Big Oh&#34;定义。

  • N ^ 2具有O(N ^ 2)
  • 1 / 2N ^ 2具有O(N ^ 2)
  • 1 / 2N ^ 2 + c * N + b也有 O(N ^ 2) - 由给定的c和b是独立于N的常数

here

检查Big Oh定义