347. 前 K 个高频元素:
题目链接 :347. 前 K 个高频元素
题目:
给定一个整数数组 nums 和一个整数 k ,请返回其中出现频率前 k 高的元素。可以按 任意顺序 返回答案。
思路:
1、使用优先队列构建小顶堆
AC代码:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
/**
使用Hash中的字典来记录每个数字在数组中出现的次数。
使用InStream流对数组nums元素类型进行转化,int->Integer包装。
使用collect()方法中的方法:对字典中已经出现的key,计算它在整个InStream中的出现次数,未出现的默认赋值1。
*/
Map<Integer, Integer> counter = IntStream.of(nums).boxed().collect(Collectors.toMap(e -> e, e -> 1, Integer::sum));
// 定义小根堆,根据数字频率自小到大排序
Queue<Integer> pq = new PriorityQueue<>((v1, v2) -> counter.get(v1) - counter.get(v2));
// 遍历数组,维护一个大小为 k 的小根堆:
// 不足 k 个直接将当前数字加入到堆中;否则判断堆中的最小次数是否小于当前数字的出现次数,若是,则删掉堆中出现次数最少的一个数字,将当前数字加入堆中。
counter.forEach((num, cnt) -> {
if (pq.size() < k) {
pq.offer(num);
} else if (counter.get(pq.peek()) < cnt) {
pq.poll();
pq.offer(num);
}
});
// 构造返回结果
int[] res = new int[k];
int idx = 0;
for (int num: pq) {
res[idx++] = num;
}
return res;
}
}