此for循环的时间复杂度是多少(与n
相关)?
for(int i = 1, j; i <= n; i = j + 1)
{
j = n / (n / i);
}
请注意,i
,j
和n
是整数变量,它们遵循整数算术运算。特别是,循环内的表达式n/(n/i)
应该解释如下:
答案 0 :(得分:3)
如果我们使用j = i;
而不是j = n / (n / i);
,则时间复杂度为O(n)。
现在是j = n / (n / i);
,假设 n = i * k + r ,其中k和r都是整数,而 r = n%i 。因此j =(i * k + r)/((i * k + r)/ i)=(i * k + r)/ k = i + r / k> = i,这意味着i的增长速度将大于如果您使用j = i;
。因此,至少时间复杂度小于O(n),我想这会给您另一个O(n)。
除了大的O符号外,还有另外两个符号(Θ和Ω),表示O(n)的下限和上限。通过找到这两个界限,可以获得时间复杂度。如果我没有记错的话,还有另外一条规则,即O(k * n)= O(n),系数k不管大小都无关紧要。
答案 1 :(得分:2)
与elaborated by taotsi一样,每次迭代中i
的增量为
inc = 1 + r/k
其中r=n%i
和k=n/i
。自r<i
起,增量为1,与i<sqrt(n)
一样长(因为i*i/n<1
在整数除法中变为0
)。此后,增量通常为2
,与i<2*sqrt(n)
一样长。这继续类似于几何级数,在sqrt(n)
上给出了因子2,即2 sqrt(n)
迭代。
如果我们用整数n = a*a+b
(即0 <= b <= 2*a
和a=int(sqrt(n))
)写b=n-a*a
,那么简单实验中的迭代总数始终是
b < a? 2*a-1 : 2*a
因此,复杂度为O(√n)(前提是在循环内完成了一些有用的工作,例如计算总迭代次数,从而不允许编译器忽略整个循环)。
答案 2 :(得分:1)
@Walter已经提供了证明,对于这一部分,我为时已晚,但这是您的代码的Python3版本,以及根据n
与{{ 1}}函数。它们看起来大致相同(最多2*sqrt(n)
)。
n = 1e9
如果看不到差异,那是因为几乎没有:D当然,人们应该始终相信数学;)
答案 3 :(得分:0)
严格按照C ++的规则,它是O(1)
。循环在执行了一定数量的不执行任何可观察的工作后终止,或者永远循环(这是未定义的行为)。符合条件的实现可能会假定未遇到未定义的行为,因此我们可能会认为它终止了。
由于程序的可观察效果不依赖于循环内发生的事情,因此允许将实现“按原样”执行为空。