这两个循环的时间复杂度是多少?

时间:2015-11-10 15:01:34

标签: c loops while-loop big-o

对于这两个while循环,我想弄清楚O的复杂性。没有详细给出这些选项:(O(log N),O(sqrt(N),O(N),O(N log N),O(N·N)。这是一个旧的考试问题,我找不到答案。

问题1

int i, j = N;
while (i < j) {
  i += 2 * j + 1;
  j++;
} 

问题2

int i = 1, j = N;
while (i < j) {
  i += i;
  j--;
}

第一个的答案是O(N·N),第二个是O(log(N))。如果有人可以解释答案,那就太好了。

3 个答案:

答案 0 :(得分:1)

第一个,如果i> = j,则为O(1)。如果i和j是正数,它将经历一次循环,并结束O(1)。

如果我是负数且j不是(&gt; = 0),你会看到我从i慢慢增长到0,然后当我是正数时,循环停止。在这种情况下,我增长至少N / 2.

如果i和j都是非常大的负数,那么在j达到0之前我会变得更负。在这段时间内,每次至少通过abs(j)变得更负,这是O(N * N)。当j达到0时,它已经是O(N * N),所以即使j == 0时它真的很快,答案应该是O(N * N)。

对于最后一种情况,我遵循一个类似的序列(假设Z是大于abs(N)的正数):

-Z,-Z-2Z + 1,-Z-2Z + 1-2(Z-1)+ 1,-Z-2Z + 1-2(Z-1)+ 1-2(Z-2) )+1 ....(直到j达到0)..然后达到一些最大的负数粗糙幅度Z平方(比如W)..然后变成W + 2 + 1,W + 2 + 1 + 4 + 1 ,W + 2 + 1 + 4 + 1 + 6 + 1 ......直到i> j。

因此,对于所有情况,更糟糕的情况是,第一个问题是O(N * N)。

第二个每次加倍,O(log N)也是。想象一下,如果j是一个非常大的数字1000000,并且i = 1.所以(i,j)将是(2,999999),(4,999998),(8,999997,(16 ...)(32,) (64,)(128,)(256,)(512,)(1024,)(2048,)(4096,)(8192,)(16384,)(32768,)(65536,)(131092,)(262144) ,(524288,999981),采取了19个步骤。

答案 1 :(得分:0)

问题1

你没有为i指定一个值,所以实际上没有什么可以说是一般情况。

但是,如果我们温和地假设i不依赖于N,则运行时为O(1)

说明

对于大型N限制:

  • i每次迭代增加2N
  • j大致不变。
  • i需要成长为N
  • 因此,需要O((N - i_0) / 2N) = O(1)时间。

这也直接显示,如果i_0f(N)的函数N,则运行时为O(f(N)/N)

问题2

运行时为O(log N)

Expanation

对于大型N限制:

  • i每次迭代加倍。
  • j大致不变。
  • i需要成长为N
  • 因此,需要O(log(N-i_0)) = O(log N)时间。

最后请注意,此问题假定N为正面,根据问题中NO(log N)的使用情况。

答案 2 :(得分:-1)

在问题1中,由于i和j都被初始化为N. while循环不会执行。因此,O(1)。

第二个问题就是O(logN),因为我每次迭代都加倍。