第3章|栈与队列
Unit 11 · 优先队列:只保留当前最有价值的 k 个候选
候选会因为时间过期或被更晚的大值支配而离开双端队列。
候选不再随窗口过期;容量超过 k 时,淘汰当前入选集合中的最弱者。
不必把所有候选排好序,
只需守住进入前 K 名的门槛。
先把原数组压缩为“元素 → 频次”,再用容量为 k 的最小堆保存当前最强候选。堆顶不是最终答案中最强的元素,而是当前入选集合中最弱、最应该被替换的元素。
题目要求
给定整数数组 nums 和整数 k,返回其中出现频率最高的 k 个元素。答案可以按任意顺序返回,并保证答案唯一。
输入、输出与复杂度目标
- 输入:整数数组
nums与合法的k; - 输出:恰好
k个最高频元素,顺序任意; - 主方法:
O(n + m log k)时间,O(m + k)空间,其中m是不同元素数。
示例
输出:[1,2]
输出:[1]
数据约束
1 ≤ nums.length ≤ 10⁵-10⁴ ≤ nums[i] ≤ 10⁴1 ≤ k ≤ 不同元素数量- 进阶要求:时间复杂度优于完整排序的
O(n log n)。
先用哈希表把 n 个原始元素压缩为 m 个“值—频次”候选,后续只处理不同元素。
离开顺序由优先级决定。最小堆可以在 O(log k) 时间插入候选,并在 O(1) 时间查看最弱候选。
容量达到 k 后,堆顶频次就是当前门槛;更弱候选不会进入最终前 K 名。
处理完任意前缀候选后,堆中恰好保存这些候选里频次最高的至多 k 个元素。
容量为 k 的最小堆 根节点 = 当前最弱入选者
当前保留集合 目标大小 k = 2
容量超过 k 时,需要最快找出并删除“当前入选者中最弱的一个”,正好是最小堆堆顶。
最终只关心谁进入前 k 名,不关心未入选元素之间的完整相对顺序。
根据当前频次卡片,前 2 个高频元素是哪两个?
分层提示 1|先压缩候选 frequency = Counter(nums) 分层提示 2|容量受限的最小堆 每个候选使用 (count, value);先 push,只有 len(heap) > k 时才 pop。 分层提示 3|为什么堆顶是门槛 heap[0] 是当前入选集合中频次最低的候选,因此超容量时应执行 heapq.heappop(heap)。 分层提示 4|输出契约 #347 允许任意顺序,只需提取堆中每个元组的 value。 请回到填空区独立完成 6 个表达式;查看提示不会解锁迁移。
O(n + m log k),适合突出优先队列与 k 较小的场景;若严格要求最坏情况始终优于完整排序,可使用按频次建桶的 O(n) 解法。本页在参考答案下方保留桶排序版本。0...n 的桶并从高频向低频收集;这里保留策略对照,不直接展示第二份完整代码。迁移题:LeetCode #692「前 K 个高频单词」
#347 只要求返回前 K 个高频元素,顺序任意;#692 除了选出前 K 个单词,还规定了完整输出顺序:频次从高到低,同频时字典序从小到大。迁移的核心因此从“维护入选集合”升级为“定义可执行的全序排名”。
原题先行:读清输出契约,再选择 Top-K 工具
先完成题面阅读检查,随后对照 #347 与 #692,并把复合排序规则映射到 Python。
题目要求与函数签名
给定字符串数组 words 和整数 k,返回出现次数最多的 k 个单词。答案必须按频次降序排列;频次相同时,按字典序升序排列。
- 1 ≤ words.length ≤ 500
- 1 ≤ words[i].length ≤ 10
- 单词只含小写英文字母
- 1 ≤ k ≤ 不同单词数量
- 进阶:O(n log k) 时间、O(n) 额外空间
官方示例
阅读锚点:示例 1 中 i 与 love 都出现 2 次,但 i 字典序更小,因此必须排在前面。
#347 前 K 个高频元素
#692 前 K 个高频单词
heapq.nsmallest 和“最佳优先”的排名键。槽位 1|压缩候选
槽位 2|定义最佳优先排名
槽位 3|只选择前 k 个
槽位 4|满足输出契约
from typing import List
from collections import Counter
import heapq
class Solution:
def topKFrequent(self, words: List[str], k: int) -> List[str]:
# 完成四个语义槽位后生成代码骨架
官方示例 1:候选排名
执行状态
可选挑战:不看生成骨架,独立重写 #692
Unit 11 Skill:先定义“更好”,再决定用堆保留集合还是输出排名
#347 的重点是用容量 k 的最小堆守住入选门槛;迁移到 #692 后,还要把频次与字典序组合为全序排名,并满足确定的返回顺序。看到 Top-K 时,先区分“只要集合”还是“还要有序输出”。