题目
找到一串数字中的第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 integerkand the stream of integersnums.int add(int val)Appends the integervalto the stream and returns the element representing thekthlargest 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
浙公网安备 33010602011771号