我对这个问题有些困惑。每一步似乎都将问题大小减半,这表明是O(logn)的时间复杂度。但如果你仔细思考一下,迭代的次数只是一个等比数列2 + 4 + 8 + ...小于n,这表明是O(n)的时间复杂度。请问有人能提供他们的见解吗?
for (int i=1; i < n; i=2i)
for (int j=i; j < n; j++)
// do something
我对这个问题有些困惑。每一步似乎都将问题大小减半,这表明是O(logn)的时间复杂度。但如果你仔细思考一下,迭代的次数只是一个等比数列2 + 4 + 8 + ...小于n,这表明是O(n)的时间复杂度。请问有人能提供他们的见解吗?
for (int i=1; i < n; i=2i)
for (int j=i; j < n; j++)
// do something
do something
是Theta(1)
,那么根据U2EF1的建议,算法应该是Theta(nlog(n))
。Sum p in [1, logn] (Sum j in [2^p, n] 1) =
Sum p in [1, logn] (n - 2^p) =
nlogn - Sum p in [1, logn] (2^p) =
nlogn - Theta(n) =
Theta(nlogn)
特别地,您可以使用闭式来计算几何级数中前n
项的最终求和。或者您可以使用更为有限的变体,类似于“将n
视为二进制数,例如1111
,并注意如果您从p = 1到log(n)
对每个幂2 ^ p
进行求和,则再次得到n
”。
闭式足以证明Theta
界限,尽管您需要使用复杂度分析中的其他常见引理来展示步骤,例如Theta(nlogn)- Theta(n)= Theta(nlogn)
。
看起来正好是 sum(sum(1, j = (2^i)..n), i = 1..log(n)) = nlog(n) - 2n + log(n) + 2 = O(n log n)
复杂度为O(n log n)
首先举个例子以便更清楚: 当n为4时,外部循环迭代2次 当n为64时,外部循环迭代6次 因此,外部循环迭代log2(n)次。
解决方案: 在外部循环的第一次迭代中,“do somethings”语句运行n次 在外部循环的第二次迭代中,“do somethings”语句运行n-2次 在外部循环的最后一次迭代中,“do somethings”语句运行n-log2(n)次
因此,在程序的总执行过程中,“do somethings”语句运行n+n-2+n-4+...+n-log2(n)次。 它等于n*log2(n)-(1+2+4+8+...+log2(n)) = n*log2(n)-(2n-1)次。 因此,复杂度为o(n log n)
n/2
次”,而是运行n-2
次。如果你把求和分开,你会发现它实际上是Theta(nlogn) - Theta(n) = Theta(nlogn)
。 - rliuTheta(n)
,我的方法会揭示出来。简单地意识到有一个与n
成比例的重复量表明该问题的紧密边界不可能是Theta(n)
。 - Slater VictoroffTheta(n)
的限制,请再仔细阅读一下(实际上,您可以看看本页上我的回答,以了解我对Theta(nlogn)
限制的证明)。您能否请解释一下以上呈现的逻辑是如何产生内部循环为j=0;j<i;j++
的另一个情况中的Theta(n)
限制的?因为这个算法确实具有Theta(n)
时间复杂度。 - rliu
j
从i
开始,到n
结束。那么内部循环要做多少工作呢? - user2357112