int j=0;
for (int i=0; i<N; i++)
{
while ( (j<N-1) && (A[i]-A[j] > D) )
j++;
if (A[i]-A[j] == D)
return 1;
}
据说此代码具有O(n)的时间复杂度,但我真的不明白。内部循环执行N次,外部循环也执行N次?可能是因为j = 0;在循环之外只能运行N次?
但是即使在内循环中只运行N次,if语句检查也应该进行N次,这将使总时间复杂度达到O(n ^ 2)?
答案 0 :(得分:15)
之所以为 O(n)的原因是,j
在{{ 1}}循环。
实际上,如果我们看一下0
循环的主体,我们会看到:
for
因此,这意味着for
最多执行 n-1 次,因为如果while ( (j<N-1) && (A[i]-A[j] > D) )
j++;
成功j++
次,则第一个约束将失败。 / p>
如果我们查看整个j
循环,就会看到:
N-1
很明显,for
循环的 body 重复了 n 次,因为我们将int j=0;
for (int i=0; i<N; i++) {
while ( (j<N-1) && (A[i]-A[j] > D) )
j++;
if (A[i]-A[j] == D)
return 1;
}
设置为for
,并在i
时停止,并且每次迭代我们都增加i=0
。
现在,根据i >= N
中的值,我们是否会(或不增加)i
循环主体中的A
(多次)。但是,无论一次迭代执行了多少次,在j
循环的末尾,for
最多只能完成 n 次,原因是我们上面提到的原因
while循环中的条件也执行一次 O(n)(准确地说,最多为 2×n-1 次):它也被执行了每次我们进入for
循环的主体,并且每次执行一次j++
命令之后,但是由于两者都是 O(n),因此可以在最多 O(n + n)次,因此 O(n)次。
for
循环中的j++
条件执行了 n 次:if
循环的每次迭代都执行一次,因此 O(n) 。
因此,这确实意味着所有“基本指令”(for
,for
,j++
,i = 0
等)均执行了固定次数 O(1)或线性次数 O(n),因此算法为 O(n)。