我试图计算以下代码段的时间复杂度
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)?
答案 0 :(得分:1)
这里让 d(n)是n的除数。
我看到你的程序为 O(d(n))每个i的除数数做 O(n)工作(最内层循环)(i从0循环)最外层循环中的n: O(n))。
其复杂性为 O(n * d(n)* n)。
对于大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