leetcode703. 数据流中的第K大元素

一、题目描述

设计一个找到数据流中第K大元素的类(class)。注意是排序后的第K大元素,不是第K个不同的元素。
你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中的初始元素。每次调用 KthLargest.add,返回当前数据流中第K大的元素。

二、解题思路及代码

  • 保存前K个最大的值,所以需要对这K个元素进行排序。
  • 因此采用优先级队列,维护一个含K个元素的小根堆。优先级队列默认队首为最小值,队首元素即小根堆堆顶元素的值。
  • 每次有新的元素加入时,如果小于堆顶元素,则直接淘汰;如果大于堆顶元素,则淘汰堆顶重新调整堆结构。对堆结构的调整实际由优先级队列完成。
class KthLargest {
     
    private PriorityQueue<Integer> queue;
    private int k;
    public KthLargest(int k, int[] nums) {
     
        this.k = k;
        queue = new PriorityQueue<Integer>(k);
        for(int num:nums){
     
            add(num);
        }
    }
    public int add(int val) {
     
        if(queue.size()<k){
     
            queue.add(val);
        }else if(val>queue.peek()){
     
            queue.poll();
            queue.add(val);
        }
        return queue.peek();
        
    }
}

三、优先级队列PriorityQueue

  • PriorityQueue是一个基于优先级的无界优先级队列,数组实现
  • 可以用该队列实现大根堆和小根堆

默认自然排序可以用于小根堆(队首为最小元素)

PriorityQueue <Integer> minHeap = new PriorityQueue<Integer>(5);

实现Comparator接口用作大根堆

PriorityQueue <Integer> maxHeap = new PriorityQueue<Integer>(11, new Comparator<Integer>() {
       
    @Override  
    public int compare(Integer o1, Integer o2) {
       
        // TODO Auto-generated method stub  
        return o2.compareTo(o1);  
    }  
});  
  • 该队列不是线程安全的,所以如果要拥有线程安全的优先级队列,需要额外进行加锁操作
  • 默认的PriorityQueue并非保证了整个队列都是有序的,只是保证了队头是最小的

四、队列的基本操作

抛出异常 返回特殊值
插入 add(e) offer(e)
移除 remove() poll()
检查 element() peek()

你可能感兴趣的:(leetcode,java,算法)