我试图确定为什么这个算法的bigO是m ^ 2 * n,以及为什么最里面的循环以m ^ 2 * n步执行。
int m=10, n=15;
int inLoop = 0, midLoop = 0, outLoop = 0;
for(int i=1;i<=m;i++)
{
outLoop++;
for(int j=1;j<=2*i-1;j++)
{
midLoop++;
for(int k=1;k<=n;k++)
{
inLoop++;
}
}
}
System.out.println("Out Loop " + outLoop);
System.out.println("Mid Loop " + midLoop);
System.out.println("Inner Loop " + inLoop);
当我运行它时,我得到内循环运行1500次,中循环运行100次,最外循环运行10次。
在运行此代码之前,我认为此代码运行第一个循环 m 次,第二个循环 m ^ 2 次,最后一个循环 n < / strong>次,使用这些值会导致内部循环输出为15,000。
显然算法似乎是在 m ^ 2 * n 步骤中执行最里面的循环,而不是我认为的那样的 m ^ 3 * n 步骤。
答案 0 :(得分:1)
求和(2i - 1),因为我从1开始到m结束是:
2 *求和(i) - 求和(1)= 2 *(m + 1)/ 2 * m - m = O(m ^ 2)
这仅适用于外圈和中圈
内环是直的,导致O(n * m ^ 2)
答案 1 :(得分:0)
我认为这个想法很明确,你可以计算每个循环的重复频率,而不是细节不清楚。现在,为了简化这些事情,您可以将这些循环分开并单独征服它们。
对于最外层循环,很明显它运行m
次。也就是说,它的复杂度是Θ(m x),其中x
是内部的复杂性。对于最里面的循环,情况也很简单,它只取决于n
的值,它是常量,因此其复杂度为Θ(n)。
中间循环是一个更复杂的循环。它的复杂性取决于i
,但i
不是常量,而是外循环的循环变量。但是,您可以使用平均值作为替换。在这种情况下,平均值非常简单,如果您绘制一个检查板,您可以看到它。在外循环的第一次迭代中,i=1
,j
只会采用单个值1
。在第二次迭代中,i=2
和j=1..3
。在第三个中,它是j=1..5
,依此类推。如果你在彼此之下绘制它们,你会得到一个类似三角形的形状。它的顶部宽度为1
,底部的宽度为2m-1
,高度为m
。因此,它的区域为((2m-1)+1)/2=m
。
将它们组合在一起,外环和中环的复杂度为Θ(m),内环的复数为Θ(n),使其整体为Θ(m²n)。