347 前k个高频元素
今天学习到的主要是优先队列这个数据结构
1: 算法思路
1.1: 首先map统计所有元素频次
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
1.2:然后是设置优先队列
(pair1,pair2) -> pair1[1] - pair2[1] 为匿名函数对象 ,此为小顶堆如果调换位置即为大顶堆
PriorityQueue<int[]> pq = new PriorityQueue<>( (pair1,pair2) -> pair1[1] - pair2[1] );
1.3:遍历map映射对,维护前k个频次最大的
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if(pq.size() < k) pq.add(new int[]{entry.getKey(), entry.getValue()});
else if(entry.getValue() > pq.peek()[1]){
pq.poll();
pq.add(new int[]{entry.getKey(), entry.getValue()});
}
}
1.4 收集结果
注意到我们要按频次从大到小的顺序
int[] ans = new int[k];
for(int i = k -1 ; i>=0; i--){
ans[i] = pq.poll()[0];
}
return ans;
2 总结
首先关于我们什么时候选择这个数据结构
当我们需要统计前k个优先元素 这类问题时候使用
如何确定大顶堆还是小顶堆,对于这题我们需要将最小的随时pop出去,故我们需要小顶堆