一、思路:
该题主要用到了堆的思想来解决该问题。并且用到了优先队列用来作为存储。java的优先队列默认的是最小堆。
最小堆的定义:根结点的键值是所有堆结点键值中最小者,称为最小堆。
首先:需要用键值对来进行存储,键:存储数组的元素,值:存储元素出现的次数
其次:1、要考虑优先队列是否满了,没满则直接存入队列,Java底层会进行堆化(最小堆)。
2、如果队列已满则需要与遍历的键对应的值进行比较如果大于我们队列首元素则替换,系统自动进行堆化将最小值换到队列首元素。
最终:打印出队列中的数据就是前k个高频率的元素。
二、画图展示:
三、代码展示:
class Solution {
//用堆的思想来实现
public int[] topKFrequent(int[] nums, int k) {
TreeMap<Integer,Integer>map = new TreeMap<>();
for(int num:nums){
if(map.containsKey(num)){//进行遍历
map.put(num,map.get(num)+1);//如果存在的时候,对值进行加一
}else{
map.put(num,1);//如果不存在相同的键时直接添加,值设置为1
}
}
PriorityQueue<freq> queue = new PriorityQueue<>();//优先队列
for(int num:map.keySet()){//通过键进行遍历
if(queue.size()<k){//如果队列的有效元素小于k的值就直接添加到队列中
queue.add(new freq(num,map.get(num)));
}else if(map.get(num)>queue.peek().value){
//如果队列满了就比较值是否大于队列中的第一个元素,大于则用键进行替换操作。
queue.remove();
queue.add(new freq(num,map.get(num)));
}
}
int[]arr=new int[k];
for(int i=0;i<k;i++){
arr[i]=queue.remove().key;
}
return arr;
}
class freq implements Comparable<freq>{//从新定义书写键值对的类
int key;
int value;
public freq(int key,int value){//通过构造方法实现初始化
this.key = key;
this.value = value;
}
public int compareTo(freq other){
return this.value-other.value ;
}
}
}