我必须找到以下程序的时间复杂度:
function(int n)
{
for(int i=0;i<n;i++) //O(n) times
for(int j=i;j<i*i;j++) //O(n^2) times
if(j%i==0)
{ //O(n) times
for(int k=0;k<j;k++) //O(n^2) times
printf("8");
}
}
我分析了这个功能如下:
i : O(n) : 1 2 3 4 5
j : : 1 2..3 3..8 4..15 5..24 (values taken by j)
O(n^2): 1 2 6 12 20 (Number of times executed)
j%i==0 : 1 2 3,6 4,8,12 5,10,15,20 (Values for which the condition is true)
O(n) : 1 1 2 3 4
k : 1 2 3,6 4,8,12 5,10,15,20 (Number of times printf is executed)
Total : 1 2 9 24 50 (Total)
但是我无法得出任何结论,因为我没有发现$ i $(基本上是O(n)和总共k(最后一行))之间存在任何关联。事实上,我不明白我们是否应该根据执行printf
的次数来查看时间复杂度,因为这将忽略执行j-for循环的O(n ^ 2)。给出的答案是O(n ^ 5),我认为这是错误的,但那么什么是正确的?为了更具体地说明我的困惑,我无法弄清楚if(j%i==0)
条件如何影响函数的整体运行时复杂性。
答案 0 :(得分:0)
答案肯定不是O(n ^ 5)。很容易看出来。假设你的第二个内部循环总是运行n^2
次,你的最内层循环总是运行n
次,即使总时间复杂度也是 O(n ^ 4)。
现在让我们看看实际的时间复杂程度。
1 。最外面的循环总是运行O(n)次。
2 。现在让我们看一下外循环的单次迭代运行第二次内循环的次数:
循环将运行
0
的时间 i = 0
0
i = 1
2
次{p> i = 2
次
....
i*i - i
j = i
次。
i*i - i
是O(i^2)
第3 即可。进入最内层循环时,只有当j
被i
除以且j
与i to i*i-1
不同时才会运行。
这意味着j
通过i*1, i*2 , i*3
.....直到i
的最后一个倍数小于i*i
。这显然是 O(i),因此对于第二次内循环的单次迭代,最内层循环运行 O(i)次,这意味着两个内循环的总迭代次数<强> O(I ^ 3)强>
总结O(i^3)
i = 0到n-1肯定会给出一个 O(n ^ 4)的术语。
因此,正确的时间复杂度为 O(n ^ 4)。