对于这两个while循环,我想弄清楚O的复杂性。没有详细给出这些选项:(O(log N),O(sqrt(N),O(N),O(N log N),O(N·N)。这是一个旧的考试问题,我找不到答案。
int i, j = N;
while (i < j) {
i += 2 * j + 1;
j++;
}
int i = 1, j = N;
while (i < j) {
i += i;
j--;
}
第一个的答案是O(N·N),第二个是O(log(N))。如果有人可以解释答案,那就太好了。
答案 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)
你没有为i
指定一个值,所以实际上没有什么可以说是一般情况。
但是,如果我们温和地假设i
不依赖于N
,则运行时为O(1)
。
说明的
对于大型N
限制:
i
每次迭代增加2N
。j
大致不变。i
需要成长为N
。O((N - i_0) / 2N) = O(1)
时间。这也直接显示,如果i_0
是f(N)
的函数N
,则运行时为O(f(N)/N)
。
运行时为O(log N)
。
Expanation
对于大型N
限制:
i
每次迭代加倍。j
大致不变。i
需要成长为N
O(log(N-i_0)) = O(log N)
时间。最后请注意,此问题假定N
为正面,根据问题中N
中O(log N)
的使用情况。
答案 2 :(得分:-1)
在问题1中,由于i和j都被初始化为N. while循环不会执行。因此,O(1)。
第二个问题就是O(logN),因为我每次迭代都加倍。