数据流中的第 K 大元素-LeetCode
703.数据流中的第 K 大元素
🎯 问题描述(来源于LeetCode)
描述:
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,而不是第 k 个不同的元素。
请实现 KthLargest 类:
KthLargest(int k, int[] nums):使用整数k和整数流nums初始化对象。int add(int val):将val插入数据流nums后,返回当前数据流中第k大的元素。
说明:
-
我们不需要保存所有的历史数据,只需要时刻保留当前最大的
k个元素即可。 -
这
k个元素中最小的那个(即堆顶),就是我们要找的第k大元素。 -
示例:
- 示例 1:
1
2
3
4
5
6
7
8
9
10
11输入:
["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); // 返回 4
kthLargest.add(5); // 返回 5
kthLargest.add(10); // 返回 5
kthLargest.add(9); // 返回 8
kthLargest.add(4); // 返回 8
- 示例 1:
💻 解题思路
思路1:小顶堆(优先队列)
代码实现
import heapq
from typing import List
class KthLargest:
def __init__(self, k: int, nums: List[int]):
self.heap = []
self.idx = k
# 遍历初始数组,复用 add 的逻辑来入堆,防止初始 nums 为空或长度不足 k
for num in nums:
self.add(num)
def add(self, val: int) -> int:
heapq.heappush(self.heap, val)
# 保持堆的大小不超过 k,淘汰掉较小的元素
while len(self.heap) > self.idx:
heapq.heappop(self.heap)
# 堆顶即为当前第 k 大的元素
return self.heap[0] if self.heap else -1
📊 性能分析
- 时间复杂度:初始化 ,每次
add操作 。因为堆的大小始终保持在 。 - 空间复杂度:O(k)$。只需要维护一个大小为 $k 的堆。
💡 思考
这道题是经典的“Top K”问题在数据流场景下的应用。使用小顶堆是解决此类问题的最优解:
- 堆中始终保留当前最大的
k个元素。 - 当新元素加入时,如果堆的大小超过
k,就弹出堆顶(即这k+1个元素中最小的那个)。 - 这样,堆顶永远指向第
k大的元素。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






