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 <= 1040 <= nums.length <= 104-104 <= nums[i] <= 104-104 <= val <= 104- 最多调用
add方法104次 - 题目数据保证,在查找第
k大元素时,数组中至少有k个元素
注意:本题与主站 703 题相同: https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/
2、解法1-优先队列
使用优先队列解题,初始化时把所有元素加入到最小优先队列pq中,添加元素时直接把元素加入pq,若pq元素个数小于k则直接返回-1,若pq元素个数超过k则逐一移除最后返回队头元素。
3、代码
var KthLargest = function (k, nums) {
this.k = k;
this.pq = new MinPriorityQueue({ compare: (a, b) => a - b });
for (const n of nums) this.pq.enqueue(n);
};
KthLargest.prototype.add = function (val) {
this.pq.enqueue(val);
if (this.pq.size() < this.k) return -1;
while (this.pq.size() > this.k) this.pq.dequeue();
return this.pq.front();
};
4、复杂度
- 时间复杂度:
- 空间复杂度:
5、执行结果
执行用时: 132 ms 内存消耗: 46.6 MB
6、解法2-计数排序
对数据流使用计数排序,首次确定第 k 大元素 kIdx 需要遍历所有元素;此后添加数据需要再确定第 k 大元素时,如果添加的数据比 kIdx 小则直接返回 kIdx ;如果添加的数据比 kIdx 小则从下标 kIdx 开始在容器 list 找到更大且元素值不为0的下标返回即可。
这个题目中使用该算法坑略多,只作参考,不建议使用。
7、复杂度
- 时间复杂度:
- 空间复杂度:
8、代码
var KthLargest = function (k, nums) {
this.k = k;
this.size = nums.length;
this.kIdx = -1;
this.list = new Array(2e4 + 1).fill(0);
for (const n of nums) this.list[n + 1e4]++;
};
KthLargest.prototype.add = function (val) {
(val += 1e4), this.list[val]++, this.size++;
if (this.size < this.k) return -1;
if (this.kIdx < 0) {
for (let i = this.list.length - 1, k = this.k; i >= 0; i--) {
if (k < this.list[i]) this.list[i] = k;
if ((k -= this.list[i]) <= 0) {
this.kIdx = i;
break;
}
}
return this.kIdx - 1e4;
}
if (this.size > this.k && val >= this.kIdx) {
this.list[this.kIdx]--;
for (let i = this.kIdx; i < this.list.length; i++) {
if (this.list[i]) {
this.kIdx = i;
break;
}
}
}
return this.kIdx - 1e4;
};
9、执行结果










