思路:
小根堆(优先队列)维护前k个元素+哈希表HashMap
代码:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
//利于哈希表存储出现的频次
Map<Integer,Integer> map=new HashMap<>();
for(int num:nums){
map.put(num,map.getOrDefault(num,0)+1);
}
//用优先队列(小根堆)来维护前k个出现频次最多的数
PriorityQueue<int[]> queue=new PriorityQueue<>(new Comparator<int[]>(){
public int compare(int[] a,int[] b){
return a[1]-b[1];
}
}
);
//动态维护前k个
for(Map.Entry<Integer,Integer> entry:map.entrySet()){
int num=entry.getKey(),value=entry.getValue();
if(queue.size()==k){
if(queue.peek()[1]<value){
queue.poll();
queue.offer(new int[]{num,value});
}
}
else{
queue.offer(new int[]{num,value});
}
}
int[] res=new int[k];
//取出前k个
for(int i=0;i<k;i++){
res[i]=queue.poll()[0];
}
return res;
}
}
分解:
1)先全部加入哈希表获得每个元素出现的频次
2)把前k个加入小根堆,剩下的逐个与队列头对比,大的就加入,并弹出一个
复杂度分析:
时间复杂度:O(NlogK)优先队列维护k个元素
空间复杂度:O(N)哈希表