BFPRT算法(1)

力扣215

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

解决方案:排序、堆、基于快排思想的解决方案、BFPRT。

本文将介绍堆和快排两种解决方案。

  • 方法一,构建大小为k小根堆,当堆大小大于k时,将堆顶弹出。代码如下
class Solution {
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> heap = new PriorityQueue();
        // int size = nums.length-k+1;
        for (int i = 0; i <nums.length ; i++) {
            heap.add(nums[i]);
            if(heap.size()>k){
                heap.poll();
            }
        }
        return heap.peek();
    }
}
  • 方法二,基于快排的思想,每次Partition过程中,得到该值的索引区间。若所求值索引区间,则直接返回。否则去取件左侧或右侧继续寻找。
package Leetcode;


import java.util.Random;

public class findKthLargest2 {
public int findKthLargest(int[] nums, int k) {

//转为第k大的索引值
k = nums.length-k;
int res = getRes(nums,0,nums.length-1,k);
return res;
}

private int getRes(int[] nums, int l, int r, int k) {
int ran = new Random().nextInt(r-l+1)+l;
swap(nums,ran,r);
//等于区间
int[] period= partition(nums,l,r);
if(k<period[0]){
return getRes(nums,l,period[0]-1,k);
}else if(k>period[1]){
return getRes(nums,period[1]+1,r,k);
}else{
return nums[period[0]];
}
}
private int[] partition(int[] nums, int l , int r){
int small = l-1;
int right =r;
int compare = nums[r];
while (l<r){
if(nums[l]<compare){
swap(nums,++small,l);
l++;
}else if(nums[l]==compare){
l++;
}else{
swap(nums,l,--r);
}
}
swap(nums,r,right);
return new int[]{small+1,r};
}
private void swap(int[] nums,int i , int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}

public static void main(String[] args) {
findKthLargest2 f = new findKthLargest2();
System.out.println( f.findKthLargest(new int[]{3,2,1,5,6,4},2));
}
}

 

posted @ 2020-03-10 21:12  HEUzbc  阅读(192)  评论(0)    收藏  举报