1.题目描述
设计一个找到数据流中第
k
大元素的类(class)。注意是排序后的第k
大元素,不是第k
个不同的元素。请实现
KthLargest
类:
KthLargest(int k, int[] nums)
使用整数k
和整数流nums
初始化对象。int add(int val)
将val
插入数据流nums
后,返回当前数据流中第k
大的元素。示例:
输入: ["KthLargest", "add", "add", "add", "add", "add"] [[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]] 输出: [null, 4, 5, 5, 8, 8] 解释: 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提示:
1 <= k <= 104
0 <= nums.length <= 104
-104 <= nums[i] <= 104
-104 <= val <= 104
- 最多调用
add
方法104
次- 题目数据保证,在查找第
k
大元素时,数组中至少有k
个元素
2.解题思路
初始化时,使用小根堆存储nums中的元素,如果nums中元素个数已经超过k个,就把超出k的部分弹出,这样就能保证堆顶元素即为第k大的元素;接下来在add操作中,如果堆中元素还不够k个,直接将其插入到堆中;如果堆中元素个数已经大于等于k个,且当前插入的元素值>=堆顶元素,那么就要把堆顶元素弹出,再把新元素加入,此时对应中对应的就是第k大的元素
3.代码实现
class KthLargest {
private PriorityQueue<Integer> pq = new PriorityQueue<>();
private int count = 0;
public KthLargest(int k, int[] nums) {
//初始化大小为k的小根堆
count = k;
for (int i = 0; i < nums.length; i++) {
pq.offer(nums[i]);
}
while (pq.size() > k) {
pq.poll();
}
}
public int add(int val) {
if (pq.size() < count) {
pq.offer(val);
} else if (val >= pq.peek()) {
pq.poll();
pq.offer(val);
}
return pq.peek();
}
}
/**
* Your KthLargest object will be instantiated and called as such:
* KthLargest obj = new KthLargest(k, nums);
* int param_1 = obj.add(val);
*/