我正在学习考试并找到了这个问题:
我无法确定复杂性,我认为它是O(n 2 )或O(n 3 )和我&# 39; m倾向于O(n 3 ) 有人可以告诉我它是什么以及为什么?
我认为它的O(n 2 )是因为在j
循环中,j = i
给出了三角形,然后是{{ 1}}循环从k
转到i + 1
,我认为这是三角形的另一半。
j
另外,如果你能告诉我它的作用?
我认为它返回正整数的加法或数组中的最大整数
但对于像public static int what(int[] arr)
{
int m = arr[0];
for (int i=0; i<arr.length; i++)
{
for (int j=i; j<arr.length;j++)
{
int s = arr[i];
for (int k=i+1; k<=j; k++)
s += arr[k];
if (s > m)
m = s;
}
}
return m;
}
这样的数组,它会返回{99, -3, 0, 1}
,我认为这是因为它有问题。如果不是我不知道它做了什么:
99
答案 0 :(得分:49)
您可以使用Sigma Notation有条不紊地处理增长复杂性的顺序:
答案 1 :(得分:15)
你有3个陈述。对于较大的n
,很明显是O(n^3)
。 i
和j
各有O(n)
,k
稍短,但仍为O(n).
算法返回连续项的最大总和。这就是为什么最后一个它返回99,即使你有0和1,你也有-3将你的总和降到最多97.
PS:三角形意味着1 + 2 + ... + n = n(n+1) / 2 = O(n^2)
答案 2 :(得分:9)
<强>代码:强>
for (int i=0; i<arr.length; i++) // Loop A
{
for (int j=i; j<arr.length;j++) // Loop B
{
for (int k=i+1; k<=j; k++) // Loop C
{
// ..
}
}
}
Big-O的渐近分析:
Loop A: Time = 1 + 1 + 1 + .. 1 (n times) = n
Loop B+C: Time = 1 + 2 + 3 + .. + m = m(m+1)/2
Time = SUM { m(m+1)/2 | m in (n,0] }
Time < n * (n(n+1)/2) = 1/2 n^2 * (n+1) = 1/2 n^3 + 1/2 n^2
Time ~ O(n^3)
答案 3 :(得分:3)
无论是否为三角形,它总是复杂度为O(N ^ 3),但当然具有较低的常数,然后是完整的三重嵌套循环。
答案 4 :(得分:3)
您可以将函数的运行时间建模为
sum(sum(sum(Theta(1), k=i+1..j),j=i..n),i=1..n)
作为
sum(sum(sum(1, k=i+1..j),j=i..n),i=1..n) = 1/6 n^3 - 1/6 n,
运行时间是Theta(n ^ 3)。
答案 5 :(得分:3)
为O(n ^ 3)。
你计算了 arr [0]和arr [arr.length - 1] 之间的任意两项,由“i”和“j”运行,这意味着C(n,2),这是n *(n + 1)/ 2次计算。
以“k”运行的每个计算之间的平均步长是(0 + arr.length)/ 2,因此总计算时间为C(n,2)* arr.length / 2 = n * n *(n + 1)/ 4,即O(n ^ 3)。
答案 6 :(得分:3)
如果你不熟悉基础理论直接应用@ MohamedEnnahdiElIdri的分析,为什么不简单地从测试代码开始呢?
首先请注意,循环边界仅取决于数组的长度,而不取决于其内容,因此关于时间复杂度,算法的作用并不重要。您也可以分析
的时间复杂度public static long countwhat(int length) {
long count = 0;
for (int i = 0; i < length; i++) {
for (int j = i; j < length; j++) {
for (int k = i + 1; k <= j; k++) {
count++;
}
}
}
return count;
}
考虑到这一点,推导假设是否更容易?如果没有,只需测试返回值是否与length
平方或length
立方体成正比...
public static void main(String[] args) {
for (int l = 1; l <= 10000; l *= 2) {
long count = countwhat(l);
System.out.println("i=" + l + ", #iterations:" + count +
", #it/n²:" + (double) count / l / l +
", #it/n³:" + (double) count / l / l / l);
}
}
...并注意一个值如何不接近任何常数上升l
而另一个值接近(不是偶然地与方法分析中与$ n $的最高幂相关联的常数)。< / p>
答案 7 :(得分:3)
这需要O(n^3)
时间,因为在三个循环中,三个不同的变量递增。也就是说,当一个内部循环结束时,它不会影响外部循环。外循环运行的次数是在输入内循环之前运行的次数。
这是最大的连续子阵列和问题。当你看到这个例子时,不言自明:
{99, 1} => returns 100
{-1, -2, -3} => return -1
{-1, 5, -2} => returns 5
{99, -3, 0, 1} => returns 99
有一种很好的算法,称为Kadane的算法(谷歌为它),它在O(n)
时间内解决了这个问题。
这就是:
Initialize:
max_so_far = 0
max_ending_here = 0
Loop for each element of the array
(a) max_ending_here = max_ending_here + a[i]
(b) if(max_ending_here < 0)
max_ending_here = 0
(c) if(max_so_far < max_ending_here)
max_so_far = max_ending_here
return max_so_far
答案 8 :(得分:2)
完整的推理如下:
让n
为数组的长度。
1)有三个嵌套循环。
2)最里面的循环执行完全j-i
次迭代(k
从i+1
到j
,包括在内。这个循环没有过早退出。
3)中间循环执行完全n-j
次迭代(j
从i
到n-1
包含),每次迭代都涉及j-i
最里面的迭代(i-i)+(i+1-i)+(i+2-i)+... (n-1-i) = 0+1+2... + (n-1-i)
。这个循环没有过早退出。
4)最外层循环执行完全n
次迭代(从i
到0
包括n-1
),每次迭代都涉及0+1+2+ ... (n-1-i)
最里面的迭代。总共(0+1+2... n-1) + (0+1+2+... n-2) + (0+1+2+... n-3) + ... (0)
。这个循环没有过早退出。
现在怎么处理这个烂摊子?你需要了解一下Faulhaber的公式(http://en.wikipedia.org/wiki/Faulhaber%27s_formula)。简而言之,它表示最多n
的整数之和为O(n^2)
;并且n
之前的整数之和为O(n^3)
,依此类推。
如果你从微积分中回忆起来,X
的原语是X^2/2
; X^2
的原语是X^3/3
。每次学位增加。这不是巧合。
您的代码在O(n^3)
中运行。