题目

找到一串数字中的第K大元素

在原数组的基础上,每次会不断插入元素

插入的同时要返回插入后第K大的元素

https://leetcode.com/problems/kth-largest-element-in-a-stream/

Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Implement KthLargest class:

  • KthLargest(int k, int[] nums) Initializes the object with the integer k and the stream of integers nums.
  • int add(int val) Appends the integer val to the stream and returns the element representing the kth largest element in the stream.

 

Example 1:

Input
["KthLargest", "add", "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
Output
[null, 4, 5, 5, 8, 8]

Explanation
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3);   // return 4
kthLargest.add(5);   // return 5
kthLargest.add(10);  // return 5
kthLargest.add(9);   // return 8
kthLargest.add(4);   // return 8

 

 

思路

tips区别

优先队列:根据自定义的优先级(更大/更小/甚至字母abc),按照优先级大的先出

普通队列:严格的先进先出

example:https://www.liaoxuefeng.com/wiki/1252599548343744/1265120632401152

优先队列经常用在dijsktra迪杰斯特拉算法,最小堆。这题先熟悉优先队列


q=new PriorityQueue<>(k);

经过定义后,q.peek()返回的则是第K大

 

找第K大的元素,即只用管大元素,小元素的顺序不用管

即每次add,

如果add的元素<第K大,那他进不进队列,对第K大都没有影响,直接忽略掉,return peek;

如果add的元素>第K大,则poll/remove排出队列中最小的,offer/add进该元素,更新队列,再return peek

 

代码

class KthLargest {
    PriorityQueue<Integer> q;
    int k;

    public KthLargest(int k, int[] nums) {
        this.k=k;
        q=new PriorityQueue<>(k);//定义返回第K大的数
        for(int n:nums){
            add(n);
        }
    }

    public int add(int val) {
        if(q.size()<k){
            //初始化
            q.offer(val);
        }
        else if(q.peek()<val){
            //只有当加入的值大于第K大时,才更新队列
            q.poll();
            q.offer(val);
        }
        //返回第K大
        return q.peek();
    }
}

 

 
leetcode 239 

Sliding Window Maximum 最大滑动窗口

https://leetcode.com/problems/sliding-window-maximum/
待复习
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        PriorityQueue<int[]> pq = new PriorityQueue<int[]>(new Comparator<int[]>() {//大顶堆
            public int compare(int[] O1, int[] O2) {
                return O2[0] - O1[0];
            }
        });
        
        for (int i = 0; i < k; ++i) {//初始的时候将0~k-1的元素加入堆中
            pq.offer(new int[]{nums[i], i});
        }
        int[] ans = new int[n - k + 1];
        ans[0] = pq.peek()[0];//滑动窗口初始最大值

for (int i = k; i < n; ++i) {//滑动窗口从从索引为k的元素开始遍历 pq.offer(new int[]{nums[i], i});//将新进入滑动窗口的元素加堆中 //当堆顶元素不在滑动窗口中的时候,不断删除堆顶堆元素,直到最大值在滑动窗口里。 while (pq.peek()[1] <= i - k) { pq.poll(); } ans[i - k + 1] = pq.peek()[0];//将在滑动窗口里的最大值加入ans } return ans; } }

 

 posted on 2021-11-29 04:10  alau  阅读(50)  评论(0编辑  收藏  举报