力扣347.前k个高频元素 | 堆 | Map.Entry | entrySet
分析:
先用hash表存数字和次数,然后使用最小堆遍历哈希表,堆的大小为k,时间复杂度为 O(n) = n log k
代码:
点击查看代码
class Solution {
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<Map.Entry<Integer,Integer>> min_heap = new PriorityQueue<>((entry1,entry2) -> entry1.getValue() -entry2.getValue());
for(Map.Entry<Integer,Integer> entry :frequencyMap.entrySet()){
if(min_heap.size() < k){
min_heap.offer(entry);
}
else if(entry.getValue() > min_heap.peek().getValue()){
min_heap.poll();
min_heap.offer(entry);
}
}
int[] result = new int[k];
for (int i = 0; i < k; i++) {
result[i] = min_heap.poll().getKey();
}
return result;
}
总结:
在处理 Map 时,如果需要同时访问键和值,推荐通过 map.entrySet() 获取 Entry 集合来遍历,而不是先获取 keySet 再通过 key 去取 value。主要原因在于性能:每次调用 get(key) 方法都可能需要计算键的哈希值并定位到对应的桶。而使用 Entry,可以直接同时拿到键和值,避免了多次不必要的哈希查找。
Map.Entry<K, V> getKey(), getValue(), setValue()
frequencyMap.entrySet()包含所有键值对的集合用于遍历
Map.Entry.comparingByValue()方便地创建用于比较值的比较器,非常适合在优先队列场景中使用。
浙公网安备 33010602011771号