思路:记录元素出现的次数用map;
要维护前k个元素,不至于把所有元素都排序再取前k个,而是新建一个堆,用小根堆存放前k个最大的数。
为什么是小根堆?因为堆每次出数据时只出堆顶,每次把当前最小的堆顶排出去
,把更大的换进来,到最后只会剩下几个最大的元素。
堆的排序复杂度是 log(K),所以整体是 n*long(K);
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer,Integer> map = new HashMap<>();
//元素和次数 放入map
for(int i : nums){
map.put(i, map.getOrDefault(i,0)+1);
}
//int[] 里面只放2两个值k-v,用来代替map的元素
PriorityQueue<int[]> xiaoDui = new PriorityQueue<>((nums1,nums2)->nums1[1]-nums2[1]);//小根堆
//遍历map里的元素,维护一个K个元素的小根堆,里面放的是大数
for(Map.Entry<Integer,Integer> item : map.entrySet()) {
if(xiaoDui.size()<k){
xiaoDui.add(new int[] {item.getKey(),item.getValue()});
}else{
//堆顶元素小时,出堆顶,入新元素
if(xiaoDui.peek()[1]<item.getValue()) {
xiaoDui.poll();
xiaoDui.add(new int[] {item.getKey(),item.getValue()});
}
}
}
//把key取出来返回
int[] ans = new int[k];
for(int i=0;i<k;i++){
ans[i] = xiaoDui.poll()[0];
}
return ans;
}
}