题目介绍
设计一个找到数据流中第 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 个元素
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/kt… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
本题的问题是求数据流中的最大的k个值,可以转化为用堆求最值问题,先实现一个最小堆,遍历nums,把nums的每项压入堆中,如果堆中的元素大小大于k了,弹出
代码
/**
* @param {number} k
* @param {number[]} nums
*/
class Heap {
constructor() {
this.data = []
}
// 向下调
shiftDown(ind = 0) {
let n = this.size() - 1
while (ind * 2 + 1 <= n) {
let tmp = ind
if (this.data[tmp] > this.data[ind * 2 + 1]) tmp = ind * 2 + 1
if (ind * 2 + 2 <= n && this.data[tmp] > this.data[ind * 2 + 2])
tmp = ind * 2 + 2
if (tmp === ind) break
this.data[tmp] = [this.data[ind], (this.data[ind] = this.data[tmp])][0]
ind = tmp
}
}
// 向上调整
shiftUp(idx) {
let pIdx = null
while (
((pIdx = Math.floor((idx - 1) / 2)),
idx && this.data[pIdx] > this.data[idx])
) {
this.data[pIdx] = [this.data[idx], (this.data[idx] = this.data[pIdx])][0]
idx = pIdx
}
}
push(val) {
this.data.push(val)
this.shiftUp(this.size() - 1)
}
pop() {
if (this.size() === 0) return
if (this.size() === 1) {
return this.data.pop()
}
this.data[0] = this.data.pop()
this.shiftDown(0)
}
top() {
return this.data[0]
}
size() {
return this.data.length
}
}
var KthLargest = function(k, nums) {
this.k = k
this.h = new Heap()
for (let val of nums) {
this.add(val)
}
console.log(this.h.data, 'datass')
};
/**
* @param {number} val
* @return {number}
*/
KthLargest.prototype.add = function(val) {
this.h.push(val)
if (this.h.size() > this.k) {
this.h.pop()
}
return this.h.top()
};
/**
* Your KthLargest object will be instantiated and called as such:
* var obj = new KthLargest(k, nums)
* var param_1 = obj.add(val)
*/