layers堆 / 优先队列
堆 / 优先队列题型:怎么识别、怎么讲、怎么练
堆题的核心是维护一个不断变化的“前沿集合”。只要题目总在问当前最优、最小、最大或 top-k,优先队列通常就能给出既快又清晰的写法。
覆盖题量
40+
推荐起手
先判断用小根堆、大根堆,还是双堆。
高频误区
堆方向选错,后面所有比较都跟着拧巴。
什么时候该想到这个模式
题目反复要求当前最小、最大或最早结束的元素。
答案依赖于维护前 k 个候选者。
每次插入后重新排序太贵,但又需要快速拿极值。
下手前的检查清单
先判断用小根堆、大根堆,还是双堆。
堆里只放后续比较真正需要的状态。
如果堆大小应固定为 k,每次 push 后立刻修正。
要明确是否允许旧状态残留,以及何时丢弃。
真正适合面试表达的解题步骤
1
先用一句话说明堆顶代表什么。
2
新候选者一旦合格就立刻入堆。
3
只有在堆顶失效或容量超限时才弹出。
4
双堆场景下,每次增删都要重新平衡。
5
最后把堆里的状态转换成题目需要的答案格式。
常见变体
维护 top-k
持续维护当前最好的 k 个候选者。
多路归并前沿
从多条有序链或流里不断取最小头部。
双堆平衡
需要同时维护前半部分和后半部分信息时使用双堆。
模板预览
Python公开预览
import heapq
heap = []
heapq.heappush(heap, value)
smallest = heapq.heappop(heap)
# max heap in Python
heapq.heappush(heap, -value)
largest = -heapq.heappop(heap)
更像真实刷题路径的推荐题单
这组题不是随机罗列,而是按“先建立识别感,再补关键变体,最后上强度”去排,适合真的拿来做一轮 pattern 复习。
入门建立直觉
#215 Kth Largest Element in an Array
在无序数组中找出第 k 大元素。
你并不需要完整排序,只需要记住目前见过的前 k 大元素。
入门建立直觉
#347 Top K Frequent Elements
返回数组中出现频率前 k 高的元素。
堆的比较维度应是频率,而不是元素值本身。
变体补齐关键状态
#23 Merge k Sorted Lists
合并 k 个有序链表。
堆里不需要整条链表,只需要每条尚未结束链表的当前头结点。
变体补齐关键状态
#295 Find Median from Data Stream
维护一个数据结构,支持每次插入后返回中位数。
一个堆维护较小的一半,一个堆维护较大的一半,两者大小差不能超过 1。
高频坑点
warning
堆方向选错,后面所有比较都跟着拧巴。
warning
top-k 问题忘了限制堆大小。
warning
堆里有延迟失效状态却没有及时清理。
warning
元组入堆后,比较主次关键字写错。
练习顺序建议
1
先做第 k 大和 top-k 频率类。
2
再刷合并 k 个链表和区间调度类。
3
然后补双堆中位数问题。
4
最后做最小区间、会议室之类更复杂的前沿扩展题。