更新时间:2025-04-01
- 算法题解目录汇总:算法刷题记录——题解目录汇总
- 技术博客总目录:计算机技术系列博客——目录页
优先整理热门100及面试150,不定期持续更新,欢迎关注!
347. 前 K 个高频元素
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按任意顺序返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
提示:
1 <= nums.length <= 105
k 的取值范围是 [1, 数组中不相同的元素的个数]
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
进阶: 你所设计算法的时间复杂度必须优于 O(n log n)
,其中 n
是数组大小。
方法一:最小堆(优先队列)
使用最小堆维护当前频率最高的k
个元素,遍历时保持堆的大小不超过k
,时间复杂度为O(n log k)
。
- 统计频率:使用哈希表记录每个元素的出现次数。
- 维护最小堆:将元素按频率加入堆,堆大小超过k时移除堆顶(最小频率元素)。
- 提取结果:堆中剩余的元素即为前k高的频率元素。
代码实现(Java):
class Solution {
public int[] topKFrequent(int[] nums, int k) {
// 统计频率
Map<Integer, Integer> freqMap = new HashMap<>();
for (int num : nums) {
freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
}
// 创建最小堆,按频率升序排序
PriorityQueue<Map.Entry<Integer, Integer>> heap = new PriorityQueue<>(
(a, b) -> a.getValue() - b.getValue()
);
// 维护堆的大小为k
for (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) {
heap.offer(entry);
if (heap.size() > k) {
heap.poll();
}
}
// 提取结果
int[] res = new int[k];
int idx = 0;
while (!heap.isEmpty()) {
res[idx++] = heap.poll().getKey();
}
return res;
}
}
方法二:桶排序
基于频率的桶排序,时间复杂度为O(n)
,适合处理大数据量。
- 统计频率:记录每个元素出现的次数及最大频率。
- 构建频率桶:将元素按频率存入对应桶中。
- 逆序收集结果:从高频率到低频率遍历桶,收集前k个元素。
代码实现(Java):
class Solution {
public int[] topKFrequent(int[] nums, int k) {
// 统计频率
Map<Integer, Integer> freqMap = new HashMap<>();
for (int num : nums) {
freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
}
// 创建桶数组
List<Integer>[] bucket = new List[nums.length + 1];
for (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) {
int freq = entry.getValue();
if (bucket[freq] == null) {
bucket[freq] = new ArrayList<>();
}
bucket[freq].add(entry.getKey());
}
// 收集结果
int[] res = new int[k];
int idx = 0;
for (int i = bucket.length - 1; i >= 0 && idx < k; i--) {
if (bucket[i] != null) {
for (int num : bucket[i]) {
res[idx++] = num;
if (idx == k) break;
}
}
}
return res;
}
}
复杂度分析
1、最小堆
- 时间复杂度:
O(n log k)
,其中n
为数组长度,k
为结果数量。
空间复杂度:O(n)
,哈希表和堆的空间。 - 优点:空间占用相对较低,适合
k
较小的情况。
缺点:当k
接近n
时,时间复杂度接近O(n log n)
。
2、桶排序
- 时间复杂度:
O(n)
,所有操作均为线性时间。
空间复杂度:O(n)
,桶数组和哈希表的空间。 - 优点:时间复杂度严格为
O(n)
,适合大数据量。
缺点:需要额外空间存储桶,最大频率较高时空间占用大。
声明
- 本文版权归
CSDN
用户Allen Wurlitzer
所有,遵循CC-BY-SA
协议发布,转载请注明出处。- 本文题目来源
力扣-LeetCode
,著作权归领扣网络
所有。商业转载请联系官方授权,非商业转载请注明出处。