我有下面的伪代码,它接受一个长度为size
的给定未排序数组,并通过查找数组中的最大值和最小值来查找范围。我只是在学习各种时间效率方法,但我认为下面的代码是Θ(n)
,因为较长的数组会添加固定数量的操作(3)。
例如,忽略max
和min
的实际赋值(因为未排序的数组是任意的,并且这些赋值事先是未知的),长度为2的数组总共只需要5个动作(包括最终范围计算)。长度为4的数组总共仅使用9个动作,再次添加最终范围计算。长度为12的数组使用25个动作。
这一切都指向Θ(n)
,因为它是一种线性关系。这是对的吗?
伪代码:
// Traverse each element of the array, storing the max and min values
// Assuming int size exists that is size of array a[]
// Assuming array is a[]
min = a[0];
max = a[0];
for(i = 0; i < size; i++) {
if(min > a[i]) { // If current min is greater than val,
min = a[i]; // replace min with val
}
if(max < a[i]) { // If current max is smaller than val,
max = a[i]; // replace max with val
}
}
range = max – min; // range is largest value minus smallest
答案 0 :(得分:3)
一个简单的方法来告诉简单的代码(如上所述)是看看有多少for()循环是嵌套的,如果有的话。对于每个“正常”循环(从i = 0 - > n),添加因子n。 [Edit2]:也就是说,如果你有这样的代码:
array a[n]; //Array with n elements.
for(int i = 0; i < n; ++i){ //Happens n times.
for(int j = 0; j < n; ++j){ //Happens n*n times.
//something //Happens n*n times.
}
}
//Overall complexity is O(n^2)
尽管
array a[n]; //Array with n elements.
for(int i = 0; i < n; ++i){ //Happens n times.
//something //Happens n times.
}
for(int j = 0; j < n; ++j){ //Happens n times.
//something //Happens n times.
}
//Overall complexity is O(2n) = O(n)
这非常简陋,但如果有人没有参加算法课程,那就很有用。
for()循环中的过程与复杂性问题无关。
[编辑]:这假设大小实际上是指数组a的大小。
答案 1 :(得分:3)
是的,这将是Θ(n)。你的推理虽然有点偏斜。
您必须查看循环中的每个项目,以便通过线性函数将其限制在上方。相反,你也受到线性函数(实际上是同一个函数)的限制,因为你无法避免查看每个元素。
O(n)只要求你绑定在上面,Omega(n)要求你绑定到下面。 Θ(n)说你双方都有界限。
答案 2 :(得分:2)
让大小为n
,然后很清楚地看到您总是进行2n
次比较,当然还有最后的单一作业。因此,您始终在此算法中执行2n + 1
次操作。
在最糟糕的情况下,您有2n
个分配,因此2n + 1 + 2n
= 4n + 1
= O(n)
。
在最好的情况下,你有0
个分配,因此2n + 1 + 0
= 2n + 1
= Ω(n)
。
因此,我们认为最佳和最差情况都是线性时间。因此,Ɵ(n)
。
答案 3 :(得分:1)
是的,这肯定是O(n)
算法。我认为你真的不需要向下钻取以查看比较次数,以得出关于算法复杂性的结论。试着看看比较的数量会随着输入的增加而变化。对于O(n)
,比较应随输入的增加而线性增加。对于O(n^2)
,它会增加n的某个倍数,依此类推。