前k个高频数的经典实现方法是堆,分为大顶堆和小顶堆,在这里我主要是使用的大顶堆,而PriorityQueue在java中是能直接实现小顶堆的,利用了一些变化,让它也可以实现大顶堆。以下先了解下PriorityQueue
一.PriorityQueue
PriorityQueue是优先队列,作用是保证每次取出的元素都是队列中权值最小的,这里涉及到了大小关系,元素大小的评判可以通过元素自身的自然顺序(使用默认的比较器),也可以通过构造时传入的比较器。
新建对象的时候可以指定一个初始容量,其容量会自动增加。
在这使用的PriorityQueue基本实现原理其实就是堆
此堆的存储方式为一维数组
leftNo = x*2
rightNo = x*2+1
parentNo = x
使用方法:
peek()和element,add(), offer(), remove()以及poll()
二.算法实例
class Solution {
public int[] topKFrequent(int[] nums, int k) {
//运用了许多不是很熟的东西
Map<Integer,Integer> map = new HashMap<>();
for (int n : nums) {
map.put(n,map.getOrDefault(n,0)+1);
}
//这块地方地方利用了优先队列自动帮你判断谁在前面谁在后面,当然可以用更简单的方法,但这个无疑是时间可以花费较少的,用空间去换时间
PriorityQueue<int[]> pq = new PriorityQueue<>((pair1,pair2)->pair2[1]-pair1[1]);
for(Map.Entry<Integer,Integer> m:map.entrySet()) {
pq.add(new int[]{m.getKey(),m.getValue()});
}
int[] res = new int[k];
int idx = 0;
while(k!=0) { //这里判断错误了,一开始判断==0导致结果错误
k--;
res[idx++] = pq.poll()[0];
}
return res;
}
}