【发布时间】:2019-09-15 01:22:15
【问题描述】:
我有一些双循环复杂度分析的练习,不知道自己做对了没有。
for i = 1 to n do
j = i
while j < n do
j = 2∗j
end while
end for
我对此的回答是O(n^2),因为第一个循环正在运行O(n) 次,而内部循环正在为外部循环的“最差”迭代进行O(n/2) 迭代。所以O(n) * O(n/2) = O(n^2)。
再进一步看,我想我可以说内部循环正在做一个部分和,即O(n/2) + O(n-1) + ... + O(1),这也是O(n)
for i = 1 to n do
j = n
while i∗i < j do
j = j − 1
end while
end for
再一次,外循环是O(n),而内循环在最坏的迭代中执行O(sqrt(n)),所以这里我认为是O(n*sqrt(n)),但我不确定这个。
for i = 1 to n do
j = 2
while j < i do
j = j ∗j
end while
end for
这里的外循环是O(n),而内循环正在为最坏的情况工作O(logn)。因此我认为这是O(nlogn)
i = 2
while (i∗i < n) and (n mod i != 0) do
i = i + 1
end while
最后,我不知道如何理解这一点。因为模数运算符。
我的问题是:
- 我在前 3 个示例中做错了吗?
- 我正在做的内部循环的“最坏情况方法”是否正确?
- 我应该如何处理最后一个练习?
【问题讨论】:
-
是的,虽然最初是正确的。每个
j等于i * 2^x,因此您最多可以在内部循环中进行log2 n迭代。复杂性不能比O(n log n)最差。到底是不是更低,这是个问题。 -
第二种情况很有趣,因为一旦
i >= sqrt(n),第二个循环就根本不会运行。对于i < sqrt(n),它将执行n - i^2迭代。这意味着像O(sqrt(n) * n + n - sqrt(n))这样的东西,我猜总共是O(n * sqrt(n))。