概述
求一个数组中第k大的值
解法一:
建立一个k个元素的最大堆,首先将数组中前k个元素放入堆中,此时堆顶元素为第k大的元素,后面继续遍历数组,比较堆顶元素与数组中元素值,当数组中元素小于堆顶元素时,将堆顶元素弹出,新元素入堆,这样最终堆顶元素即为第k大。
可以直接利用Java中优先级队列,这里传入一个比较器来构造最大堆。
public static int topK3(int[] arr, int k){
PriorityQueue<Integer> q = new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
for(int i=0; i<k; i++){
q.add(arr[i]);
}
for(int i=k; i<arr.length; i++){
if(arr[i]<q.peek()){
q.poll();
q.add(arr[i]);
}
}
return q.peek();
}
解法二:
利用快速排序中partition函数,当partition返回元素坐标q==k-1时,说明q前面已经有k-1个元素比q位置元素小,则arr[q]即为第k大元素。如果q>k-1 说明第k大元素在前半部分,否则在后半部分。
public static int topK(int[] arr, int k, int lo, int hi){
int q = partition(arr, lo, hi);
//q==k-1时,arr[q]本身是第K大
if(q==k-1)
return arr[q];
else if(q>k-1)
return topK(arr, k, lo, q-1);
else
return topK(arr, q-k, q+1, hi);
}
public static int topK2(int[] arr, int k){
int lo = 0;
int hi = arr.length-1;
int q = partition(arr, lo, hi);
while(q!=k-1){
if(q>k-1)
q = partition(arr, lo, q-1);
else
q = partition(arr, q+1, hi);
}
return arr[q];
}
public static int partition(int[] arr, int lo, int hi){
int r = arr[hi];
int i = lo - 1;
for(int j=lo; j<hi; j++){
if(arr[j]<r){
i++;
swap(arr, i, j);
}
}
swap(arr, i+1, hi);
return i+1;
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
最后
以上就是威武金鱼为你收集整理的算法12--topK求一个数组中第k大的数的全部内容,希望文章能够帮你解决算法12--topK求一个数组中第k大的数所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复