我试图通过解决问题来教自己订单统计
在O(n)时间内找到数组中的第k个最大元素。
我的Java实现如下。
Qn:我不确定如何确定代码的复杂性。据我所知,它不超过n。它是否正确?或者我该怎么做?
已经调整了第215页的算法,介绍了Algo麻省理工学院出版社。
package intp;
public class IntP {
public static void main(String[] args) {
int[] qn = {10,22,33,4,5,6,1};
int[] res = {0,0};
int q;
int k =3;
q=k;
while (k>=1){
res = findMax(qn,k);
qn[res[1]]=0;
k=k-1;
}
System.out.println("Largest element number "+q+ " is: "+res[0]);
}
public static int[] findMax(int[] a,int k){
int pos=0;
int max = a[0];
int[] ans= {0,0};
for(int i= 1;i<a.length;i+=2){
if (i+1==a.length){
if (a[i]>max){
max=a[i];
pos=i;
}
break;
}
if (a[i]>a[i+1] && a[i]>max){
max=a[i];
pos=i;
}
else if (a[i+1]>max && a[i+1]>max){
max= a[i+1];
pos=i+1;
}
}
ans[0]=max;
ans[1]= pos;
return ans;
}
}
答案 0 :(得分:2)
findMax
的首次复杂性:
Time(findMax) = 3 + 1/2 n * (4 + 2) + 1 + 3
Time(findMax) = 3 n + 7
Time(findMax) ~ n
Time(findMax) ~ O(n)
然后main
的时间复杂度:
Time(main) = 5 + k * (3 + Time(findMax))
Time(main) = k * (3 n + 10) + 5
Time(main) = 3 k n + 10 k + 5
Time(main) ~ k * Time(findMax)
Time(main) ~ O(kn)
注意:我将任何托管指令视为1次操作
答案 1 :(得分:0)
重复选择最大值是实现Kth选择的一种不好的方法(除了非常小的K)。它需要最坏时间O(KN)。
更好的方法是对数组进行排序,例如使用Quicksort,在预期的O(N.Lg(N))中执行。无论如何,最坏情况的时间是二次的,O(N²)。
更好一点,Quickselect,Quicksort的“剥离”版本。接近线性时间O(N),但它保持最坏情况O(N²)。
真正最优的方法(在渐近意义上)是中位数中位数,具有保证的O(N)行为。
我首选的天真方法:
for (i= 0; i < n; i++) // Try every element a[i]
{
int r= 0;
for (j= 0; j < n; j++) // Evaluate the rank by counting inferior elements
{
r+= a[j] < a[i] || (a[j] == a[i] && j < i); // Mind the equal elements
}
if (r == k) // Desired rank
return i;
}