我无法弄清楚下面代码的复杂性。虽然,我知道正确的答案。只是想知道为什么会这样。
void main()
{
int i, j, n, x;
for(i=0; i < n; i++)
{
for(j=0; j*j <= n; j++)
{
x=10;
}
}
}
复杂度为O(n√n)。
答案 0 :(得分:3)
外部循环执行n
次迭代。
内循环执行sqrt(n)
次迭代(因为它将j
平方与n
进行比较。)
循环体需要恒定的时间。
将所有三个乘以O(n sqrt(n))
。
P.S。一个好的编译器可能会为这个精确的循环生成O(1)
代码。
答案 1 :(得分:2)
第一个循环可以从1到n,第二个循环从1到sqrt(n)。 这就是复杂度为O(n * sqrt(n))的原因。
答案 2 :(得分:1)
外部循环为O(n) - 执行时间与元素数量成正比。
但是它有一个内循环,它对外循环的每次迭代执行一次。当数字或执行的平方等于n时,这个停止。也就是说,它对外循环的每次迭代执行√n次。
因此总复杂度为O(nx√n),写为O(n√n)。
答案 3 :(得分:0)
画一张桌子,你就知道为什么了。假设n = 10
:
i | j
-----+-----
0 | 0 0*0 <= 10 ? Yes | |
0 | 1 1*1 <= 10 ? Yes | |
0 | 2 2*2 <= 10 ? Yes | → O(√n) Times |
0 | 3 3*3 <= 10 ? Yes | |
0 | 4 4*4 <= 10 ? NO! | |
1 | 0 ... |
1 | 1 | → O(n) Times
.. | .. |
.. | .. |
9 | 0 |
9 | 1 |
9 | 2 |
9 | 3 |
9 | 4 |
现在您发现内循环执行O(√n)次。外循环很简单,需要O(n)。将它们相乘会产生您获得的结果。
答案 4 :(得分:0)
使用Sigma表示法,您可以获得确切的迭代次数加上增长复杂度的顺序(经验验证):