这个for循环的时间复杂度是多少(与`n`有关)?

时间:2018-11-06 13:07:19

标签: c++ algorithm time-complexity

此for循环的时间复杂度是多少(与n相关)?

for(int i = 1, j; i <= n; i = j + 1)
{
        j = n / (n / i);
}

请注意,ijn是整数变量,它们遵循整数算术运算。特别是,循环内的表达式n/(n/i)应该解释如下:

enter image description here

4 个答案:

答案 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%ik=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*aa=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

这是情节: enter image description here

如果看不到差异,那是因为几乎没有:D当然,人们应该始终相信数学;)

答案 3 :(得分:0)

严格按照C ++的规则,它是O(1)。循环在执行了一定数量的不执行任何可观察的工作后终止,或者永远循环(这是未定义的行为)。符合条件的实现可能会假定未遇到未定义的行为,因此我们可能会认为它终止了。

由于程序的可观察效果不依赖于循环内发生的事情,因此允许将实现“按原样”执行为空。