我很担心这个算法的运行时间是O(n^2)
还是O(n^3)
。该计划如下:
int count=0;
for (int i =0; i<n; i++){
for (int j =i+1; j<n; j++){
for (int k =j+1; k<n; k++){
count++;
}
}
}
System.out.print("count: " + count);
我使用了n=7
的示例。这给了我35
的结果(计数)。我知道i和j循环一起具有高斯和的运行时间,即1+2+3...n=O(n^2)
。我试着通过做一些计算来弄清楚所有3个循环的完整运行时间。
我使用了由
我发现制作高斯总和并加上它们会给我正确的结果。(从i=2
开始直到i=n-1
)我得到的公式是:
我如何删除总和标志并获得常规&#34;公式&#34;?
感谢您的时间!
答案 0 :(得分:1)
From Wikipedia,强调我的:
Big O表示法是一种数学符号,用于描述当参数趋向特定值或无穷大时函数的限制行为。
考虑当 n 接近无穷大时会发生什么:你正在考虑 n - 2 元素的总和。当 n 接近无穷大时, -2 将成为一个无用的小术语,因此你可以忽略*它并乘以 n 。 / p>
(*你没有正确地忽略它,但是存在一个常量 k ,这样你的外环/求和运行时间将少于 kn 次,这意味着它仍然属于 O(n)。)
按照类似的逻辑,你要求的表达式属于 O(n²),因为尽管 i ,你总结的术语将严格小于kn²表示 k 的某些常数值。 i 可能在2和 n - 1 之间变化,但这对(n - i)((n - i)+ 1)的方式没有任何影响/ 趋势,因为 n 接近无穷大;对于 k 的某个常数值,它仍然小于kn²,因此该函数仍在 O(n²)中。
因为您正在对 O(n²)订单的 O(n)值求和,所以您的函数在 O(n³)总体而言。
答案 1 :(得分:1)
虽然Jeff Bowman的回答是正确的,但我觉得能够提出确切的公式很有意思并且很有用。你最终得到的公式是正确的,但你提到你要“删除总和符号”,有效地简化了公式。
在下文中,sum_{i=a}^{b}[y(i)]
表示从y(i)
到i
的{{1}} a
的总和。
从您的公式开始:
b
您可以清楚地看到count = sum_{i=2}^{n-1}[(n-i)*(n-i+1) / 2]
2*count = sum_{i=2}^{n-1}[(n-i)*(n-i+1)]
2*count = sum_{i=2}^{n-1}[(n-i)^2 + (n-i)]
2*count = sum_{i=2}^{n-1}[(n-i)^2] + sum_{i=2}^{n-1}[(n-i)]
2*count = sum_{i=1}^{n-2}[i^2] + sum_{i=1}^{n-2}[i]
2*count = (n-2)(n-1)(2*(n-2)+1)/6 + (n-2)(n-1)/2
12*count = (n-2)(n-1)(2*n-4+1) + (n-2)(n-1)*3
count = (n-2)(n-1)(2*n)/12
count = (n-2)(n-1)(n)/6
位于count
但不在O(n^3)
。
答案 2 :(得分:0)
Big-Omega是一个下限,所以说明你的算法有一个Ω(n 2 )就足够了,因为 i , j 和 k 都运行绑定到 n 的某个值。