题目解析:题目就是求一个数组中,元素频率出现次数,前k高的元素,返回前k高的元素数组
思路:
1,这类统计出现频率问题,首选map统计,
2,再对频率进行排序,使用优先级队列
3,返回前k个元素
知识点:
1,优先级队列:对于加入到队列中的元素,会进行排序,使得队列中的元素始终有序。其原理:优先级队列其实是一个堆,其对外接口是从队头取元素,队尾加元素。
2,比较器:对于一个类,若对类排序,需重写自定义比较器
3,Java HashMap getOrDefault() 方法
//getOrDefault:有key时,使用value,没有时,使用默认值0
int f = freq.getOrDefault(nums[i],0)+1;
这道题:我们使用小顶堆,每次将最小元素弹出,最后小顶堆里面积累的是前k个最大元素。
代码实现:
class Solution {
/**
1,整理出现的频率,使用hashmap
*/
public int[] topKFrequent(int[] nums, int k) {
//整理好频率了,这几行
Map<Integer,Integer> freq = new HashMap<>();
for(int i=0;i<nums.length;i++){
//getOrDefault:有key时,使用value,没有时,使用默认值0
int f = freq.getOrDefault(nums[i],0)+1;
freq.put(nums[i],f);
}
//开始挑选最大的k个元素,使用堆,
//使用优先队列
PriorityQueue<Integer> minHeap = new PriorityQueue<>(
new Comparator<Integer>(){
@Override
public int compare(Integer a,Integer b){
//比较的是频率,因为是比较的数字,所以如果升序,那么就是正常的这样前面-后面
int c = freq.get(a)-freq.get(b);
return c;
}
}
);
//上面优先队列已经做好了,开始往队列里面放东西
//只放k个元素,freq.keySet获取键
for(Integer elem:freq.keySet()){
//小顶堆添加元素,会自动排序
minHeap.add(elem);
if(minHeap.size()>k){
minHeap.remove(); //删除顶部元素,顶部是最小的
}
}
//小顶堆中全部都是答案,将其集合添加到数组
int[] ans = new int[k];
for(int i=0;i<k;i++){
ans[i] = minHeap.remove();
}
return ans;
}
}
github的参考链接比较有意思
https://blog.csdn.net/qq_17550379/article/details/80957793