你好,我曾经使用Big O表示法犯罪,所以我有点生气。
我知道有一个循环,循环n次是O(n),并且有一个循环在另一个循环n次的循环中循环n次是O(n ^ 2)。
但是在下面的代码片段中,我有一个循环n次循环,并且在循环中循环n次i。
此代码的最差和最佳O符号是什么?
最糟糕的是它在没有发现碰撞的情况下运行,最好的情况是在2个第一个矩形之间发生碰撞。
class TestClass
{
bool Run(List<Rectangle> R)
{
var b = false;
var i = 0;
var n = R.Count;
var j = 0;
while ((i < n-1 ) && !b )
{
j = i + 1;
while (j<n && !b)
{
if ((R[i].x >= R[j].x - R[i].w) && (R[i].x <= R[j].x + R[j].w))
if ((R[i].y <= R[j].y + R[i].h) && (R[i].y >= R[j].y - R[j].h))
b = true;
j++;
}
i++;
}
return b;
}
}
public class Rectangle
{
public int x;
public int y;
public int w;
public int h;
}
答案 0 :(得分:3)
正如一位评论者所指出的,Big-O始终是最糟糕的情况,所以如果增加R.Count的值会使你的最坏情况增加的速度大于n * log(n) ,你进入了n²的领域。
由于你有一个双嵌套while
循环,没有额外的方法调用,所以我一眼就知道它是O(n²)。
但是,在这种情况下,由于i和j从不递增,并且n
从不递减,并且您的循环都基于i或j小于n
,因此该函数将向右退出离开(基于你的if
陈述),或永远不会。
O(infinity)?
修改强>
好的,现在你增加它们,每次运行时n *(ni)位基本上平均为n *(n / 2)(不是所有运行的平均,但是而是每个运行的平均值。这是因为当你穿过外环时,你将会做(n,n-1,n-2,...,3,2,1)内环。如果您将此设置折叠起来,则可以轻松总结循环次数:
n + 1 == n + 1
(n-1) + 2 == n + 1
(n-2) + 3 == n + 1
...
所以你最终得到n + 2个n + 1个实例,它出现在(n²+ n)/ 2。从大O角度来看,这与n²相同。
答案 1 :(得分:1)
您的实际最差情况下的运行时间是n X n / 2 =n²/ 2。抛弃常数,它是O(n²)