347. 前 K 个高频元素
347. 前 K 个高频元素
题目链接:347. 前 K 个高频元素
题目描述
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
核心思考:桶排序(Bucket Sort)加速
常规思路是统计频率后进行排序($O(N \log N)$)或者使用堆($O(N \log k)$)。但在本题中,频率的最大值不会超过数组的长度 $N$。利用这一特性,我们可以使用桶排序在 $O(N)$ 时间内解决。
- 统计频率:首先使用哈希表(Python 中的
Counter)记录每个数字出现的次数。同时找出出现的最高频率max_count。 - 建立桶:创建一个长度为
max_count + 1的列表b,每个位置b[i]也是一个列表。b[i]的含义是:所有出现次数刚好为i次的数字集合。
- 分配入桶:遍历哈希表,根据频率将对应的数字放入对应的桶中。
- 逆序提取:从频率最高的桶(
b[max_count])开始向低频方向遍历。依次提取桶中的数字加入结果集,直到结果集的长度达到k。
这种方法巧妙地利用了“频率是有界的”这一物理现实,避开了基于比较的排序,从而实现了线性时间复杂度。
解题思路 (Python)
1 | class Solution: |
复杂度分析
- 时间复杂度:$O(N)$,其中 $N$ 是数组的长度。频率统计需 $O(N)$,入桶需 $O(N)$,逆序扫描桶数组总共处理的元素个数也不会超过 $N$。
- 空间复杂度:$O(N)$。主要开销为存储频率的哈希表和用于桶排序的嵌套数组。
说明:为了严谨,代码增加了一个对ans的截取处理[:k]以应对同一个频率桶包含多个元素导致ans长度超过k的边界情况。