数组中最小的k个数&第k大的数字

例题1:数组中最小的k个数

思路:采用大根堆维护数组中的前k个最小的值。首先将k个数插入大根堆,然后从k+1个数开始遍历数组,遍历到比大根堆中堆顶的数要小的数值,就弹出堆顶的数,并插入当前遍历到的数。最后,将k个最小值存储到数组中返回即可。

class Solution {
    public int[] smallestK(int[] arr, int k) {
        int[] vec = new int[k];//创建一个数组存放k个元素
        if (k == 0) { 
            return vec;
        }
        PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(new Comparator<Integer>() {//大根堆需要用户提供比较器,采用Comparator接口,重写该接口中的compare方法
            public int compare(Integer num1, Integer num2) {
                return num2 - num1;
            }
        });
        for (int i = 0; i < k; ++i) {//将k个数值放入大根堆
            maxHeap.offer(arr[i]);
        }
        for (int i = k; i < arr.length; ++i) {
            if (maxHeap.peek() > arr[i]) {//查看是否大于大根堆的堆顶元素
                maxHeap.poll();//堆顶元素弹出
                maxHeap.offer(arr[i]);//较小的值放入大根堆
            }
        }
        for (int i = 0; i < k; ++i) {
            vec[i] = maxHeap.poll();//将k个最小的数存储在数组中
        }
        return vec;
    }
}

 例题2:数组中第k大的数字

思路:找到k个最大的数字,其中最小的数字即为数组中第k大的数字。采用小根堆存储k个最大的数字,每次从数组中,然后判断数组中其他数字是否小于堆顶的最小值,如果新读入的数字比堆顶数字的值要大,那么就弹出堆顶数字,将新的数字入堆。

class KthLargest{
   private PriorityQueue<Integer> minHeap;
   private int size;
 
   public KthLargest(int k, int[] nums){
      size=k;
      minHeap=new PriorityQueue<>();
      for(int x: nums){//存储k个元素到小根堆
          add(x);
      }
   }

   public int add(int val){
      if(minHeap.size()<size){//如果小根堆中的元素小于k个,加入新元素
         minHeap.offer(val);
      }else if(val>minHeap.peek()){//判断新读入的值是否比堆顶数字的值要大
         minHeap.poll();
         minHeap.offer(val);
      }
      return minHeap.peek();
   }
}

猜你喜欢

转载自blog.csdn.net/m0_72000264/article/details/130409241
今日推荐