1. 前K个高频元素问题解析
这个问题在算法面试中非常经典,给定一个非空的整数数组,返回其中出现频率前K高的元素。看似简单,但考察了数据结构选择、算法优化和编码实现的多方面能力。
举个例子,对于数组[1,1,1,2,2,3]和K=2,应该返回[1,2],因为1出现3次,2出现2次,3出现1次。这个问题在实际开发中也有很多应用场景,比如统计用户行为中的高频事件、分析日志中的异常IP等。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解决思路与算法选择
2.1 暴力解法分析
最直观的解法是:
- 统计每个元素的出现频率
- 对频率进行排序
- 取前K个元素
这种方法时间复杂度为O(nlogn),主要消耗在排序步骤。虽然能解决问题,但在面试中显然不够优秀。
2.2 优化思路 - 堆的应用
更优的解法是使用最小堆(Min Heap):
- 先用哈希表统计频率 - O(n)
- 维护一个大小为K的最小堆 - O(nlogK)
- 输出堆中元素
这种方法将时间复杂度降低到O(nlogK),当K远小于n时效率提升明显。为什么用最小堆而不是最大堆?因为我们需要保留频率最高的元素,最小堆可以方便地淘汰当前堆中最小的元素。
3. Java实现详解
3.1 基础实现
java复制public int[] topKFrequent(int[] nums, int k) {
// 统计频率
Map<Integer, Integer> frequencyMap = new HashMap<>();
for (int num : nums) {
frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
}
// 创建最小堆
PriorityQueue<Integer> heap = new PriorityQueue<>(
(a, b) -> frequencyMap.get(a) - frequencyMap.get(b)
);
// 维护堆的大小为k
for (int num : frequencyMap.keySet()) {
heap.offe
