代码段的时间复杂度

时间:2016-09-29 05:44:19

标签: algorithm time-complexity

我试图计算以下代码段的时间复杂度

sum = 0;
for(i = 0; i <= n; i++) {
  for(j = 1; j <= i; j++) {
    if(i % j == 0) {
      for(k = 0; k <= n; k++) {
        sum = sum + k;          
      }        
    }
  }
}

我认为,在第一次循环的N次迭代中,只有1个值为0,允许进入K循环,而i = 1 ...... N,K循环从不运行。

因此,只有1个值的I运行j次循环N次并且k循环N次,而对于其他值I我只有J循环运行N次

那么,TC = O(N ^ 2)?

2 个答案:

答案 0 :(得分:1)

这里让 d(n)是n的除数。

我看到你的程序为 O(d(n))每个i的除数数做 O(n)工作(最内层循环)(i从0循环)最外层循环中的n: O(n))。

其复杂性为 O(n * d(n)* n)

Reference

对于大n, d()~O(exp(log(n)/ log(log n)))

因此总体复杂度为 O(n ^(2 + 1 / log(log n)))

答案 1 :(得分:0)

我得到了另一个答案。让我们用一个抽象的func()代替内部循环:

for(i=0;i<=n;i++) {
  for(j=1;j<=i;j++) {
    if(i%j==0) {
      func();        
    }
  }
}

首先,忘记调用func(),计算所有(i%j)的复杂度M是O(n ^ 2)。

现在,我们可以问自己调用func()的次数。它为我的每个除数调用一次。也就是说,每个i都称为d(i)次。这是Divisor summatory function D(n)。对于大n,D(n)~n log n。 所以func()被称为n log n次。同时,func()本身具有O(n)的复杂性。因此它给出了复杂度P = O(n * n log n)。

总复杂度为M + P = O(n ^ 2)+ O(n ^ 2 log n)= O(n ^ 2 log n)

修改 誓,感谢downvote!我想我需要使用python来证明它。 此代码打印出n,为n调用内循环的次数,并输出后者与除数累加函数的比率

import math

n = 100000
i = 0
z = 0
gg = 2 * 0.5772156649 - 1
while i < n:
  j = 1
  while j <= i:
    if i % j == 0:
      #ignoring the most inner loop just calculate the number of times it is called
      z+=1

    j+=1

  if i > 0 and i % 1000 == 0:
    #Exact divisor summatory function, to make z/Di converge to 1.0 quicker
    Di = (i * math.log(i) + i * gg)
    #prints n Di z/Di
    print str(i) + ": " + str(z) + ": " + str(z/Di)

  i+=1

输出样本:

24000: 245792: 1.00010672544
25000: 257036: 1.00003672445
26000: 268353: 1.00009554815

所以最内层循环称为n * log n次,总复杂度为n ^ 2 * log n