#347
Medium
堆 / 优先队列
Top K Frequent Elements
返回数组中出现频率前 k 高的元素。
返回出现频率前 k 高的元素。核心拆法很清楚:先统计频次,再用堆只保留 top-k 前沿。
ArrayHeap
题目定位
频次统计负责生成候选,大小为 k 的堆负责只保留最重要的那批元素。
关键观察
堆的比较维度应是频率,而不是元素值本身。
目标复杂度
O(n log k) / O(n)
这题的解法思路怎么拆
1
先用频次表统计每个值出现了多少次。
2
维护一个按频次排序、大小为 k 的小根堆。
3
每次堆大小超过 k,就弹出频次最小的那个元素。
4
最终堆里剩下的,正好就是频次前 k 高的元素。
拿一个例子顺一遍
1
例如 nums = [1,1,1,2,2,3], k = 2。
2
频次表变成 {1: 3, 2: 2, 3: 1}。
3
把这些键值对依次入堆,并始终保持堆大小不超过 2,最终留下的是 1 和 2。
4
因此答案是 [1, 2],顺序通常不重要。
参考实现
Pythonfrom collections import Counter
import heapq
def topKFrequent(nums: list[int], k: int) -> list[int]:
counts = Counter(nums)
heap: list[tuple[int, int]] = []
for value, frequency in counts.items():
heapq.heappush(heap, (frequency, value))
if len(heap) > k:
heapq.heappop(heap)
return [value for _, value in heap]
常见坑点
warning
只把值压堆,没有把频率作为比较键。
warning
明明输出顺序通常不重要,却多做了无意义排序。
高频追问
什么时候桶排序会比堆更合适?
如果输入是流式到达,该怎么做?
继续刷相关题
先把 堆 / 优先队列 这个模式刷成体系,再去做更难变体。