发布于2026-07-02 阅读(0)
扫一扫,手机访问
要用堆来找出第 K 小的元素,核心思路其实很简单:别想着先把整个数组排完序,也别一次性建一个大堆然后慢慢取。正确的做法是,用一个大小为 K 的大根堆,一边遍历一边维护——让堆顶始终成为当前已见过的元素中第 K 小的那个候选值。
你可能会想:“为什么要用大根堆?用小根堆不行吗?” 别急,下面就来拆解这个逻辑。

我们的目标是找到“第 K 小”,换句话说,我们只关心所有元素中最小的那 K 个数,并且要从中找出最大的那个(也就是第 K 小的那个)。大根堆恰好能高效地保存这 K 个数里的最大值。
换句话说,你手里始终攥着当前最小的 K 个数,堆顶就是这 K 个里最大的那个。只要新来的数比这个“门槛”小,它就替换掉门槛,门槛自然就降低了。这招非常巧妙,避免了全量排序的浪费。
整个流程不需要预先建堆,也不用对原始数组排序,按顺序扫描一遍即可:
priority_queue,Ja va 的 PriorityQueue 默认是小根堆,记得传入 Comparator.reverseOrder())。你看,整个过程干净利落,没有多余的步骤。
这个方案特别适合在线流式处理,或者数据量很大但 K 相对较小的场景:
可以说,这是用空间换时间的典范——而且空间换得也很克制。
几个容易踩坑的小细节,提前说清楚就能避免很多调试时间:
heapq 默认只支持小根堆,要模拟大根堆,常见的做法是存负值。但直接使用 heapq._heapify_max 这种非公开 API 并不推荐,不够稳妥。更可靠的方式是用 heapq 维护小根堆去求第 K 大,或者改用 sortedcontainers 等第三方库。总的来说,用大根堆求第 K 小是一个典型且优雅的“筛选”思路,理解和实现起来都不复杂,关键是选对了工具。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8