题目
题解
堆
利用优先队列PriorityQueue
对统计的频次进行排序,优先队列底层使用的是堆排序,采用小顶堆,每次将堆顶(前k个元素中最小的)与新元素的频次比较,如果小于,则弹出堆顶,新元素加入堆中
重点记一下优先队列的代码:
//默认小顶堆,大顶堆需要重写比较器
PriorityQueue<int[]>queue=new PriorityQueue<>(new Comparator<int[]>(){
//数组类型元素,重写比较器
public int compare(int[] n,int[] m){
return n[1]-m[1];
}});
本题代码:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
//统计数字及频次
Map<Integer,Integer>map=new HashMap<>();
for(int i=0;i<nums.length;i++){
map.put(nums[i],map.getOrDefault(nums[i],0)+1);
}
//优先队列排序规则
PriorityQueue<int[]>queue=new PriorityQueue<>(new Comparator<int[]>(){
public int compare(int[] n,int[] m){
return n[1]-m[1];
}});
//优先队列(堆排序)
//Java的entry是一个静态内部类,实现Map.Entry< K ,V> 这个接口
for(Map.Entry<Integer,Integer>entry:map.entrySet()){
int key=entry.getKey(),count=entry.getValue();
//前k个满了,置换
if(queue.size()==k){
if(count>queue.peek()[1]){
queue.poll();
queue.offer(new int[]{key,count});
}
}
else
queue.offer(new int[]{key,count});
}
//优先队列结果存入结果数组
int[] res=new int[k];
for(int i=0;i<k;i++){
res[i]=queue.poll()[0];
}
return res;
}
}
时间复杂度: O ( n l o g k ) O(nlogk) O(nlogk)
空间复杂度: O ( n ) O(n) O(n)