另一个大O符号问题...对于代码的大O是什么:
for (int i = n; i > 0; i = i / 2){
for (int j = 0; j < n; j++){
for (int k = 0; k < n; k++){
count++;
}
}
}
我的想法:
所以打破它,我认为外部循环是O(log2(n))
,然后每个内部循环都是O(n)
,这将导致O(n^2 * log2(n))
问题#1是正确的吗?
问题#2: 当组合嵌套循环时,它总是像每个循环的大O一样简单吗?
答案 0 :(得分:10)
当循环计数器不相互依赖时,它总是可以从内向外工作。
最里面的循环总是花费时间O(n),因为无论j和i的值如何,它都会循环n次。
当第二个循环运行时,它运行O(n)次迭代,在每次迭代时执行O(n)工作以运行最内层循环。这需要时间O(n 2 )。
最后,当外循环运行时,每次迭代都会执行O(n 2 )工作。它也运行O(log n)迭代,因为它的运行时间等于在达到1之前必须将n除以2的次数。因此,总工作量为O(n 2 log n)中。
通常,您不能将循环相乘,因为它们的边界可能相互依赖。但是,在这种情况下,由于没有依赖关系,运行时只能成倍增加。希望上面的推理可以解释为什么会这样 - 这是因为如果你从内到外思考每个循环做了多少工作以及它做了多少次,那么运行时最终会成倍增加。
希望这有帮助!
答案 1 :(得分:2)
logN
,其他两个是N
,每个O(N^2*LogN)
答案 2 :(得分:2)
为了更正式地回答这个问题(注意:稍微),说T(n)
是完成算法所需的时间(或操作次数)。然后,对于外部循环T(n) = log n*T2(n)
,其中T2(n)
是里面的操作数循环(忽略任何常量)。类似地,T2(n)= n * T3(n)= n * n。
然后,使用以下定理:
如果f 1 (n)= O(g 1 (n))且f 2 (n)= O(g < sub> 2 (n)),然后f 1 (n)×f 2 (n)= O(g 1 (N)×G <子> 2 子>(n))的
(source and proof)
这使我们得到T(n)= O(n 2 logn)。
“组合嵌套循环”只是这个定理的一个应用。问题在于确定每个循环使用的确切操作数量,在这种情况下很简单。
答案 3 :(得分:0)
您可以正式使用Sigma Notation,忠实地模仿您的循环: