PriorityQueue+347前k个高频数

244 阅读1分钟

前k个高频数的经典实现方法是堆,分为大顶堆和小顶堆,在这里我主要是使用的大顶堆,而PriorityQueue在java中是能直接实现小顶堆的,利用了一些变化,让它也可以实现大顶堆。以下先了解下PriorityQueue

一.PriorityQueue

PriorityQueue是优先队列,作用是保证每次取出的元素都是队列中权值最小的,这里涉及到了大小关系,元素大小的评判可以通过元素自身的自然顺序(使用默认的比较器),也可以通过构造时传入的比较器。

新建对象的时候可以指定一个初始容量,其容量会自动增加。

在这使用的PriorityQueue基本实现原理其实就是堆

此堆的存储方式为一维数组 leftNo = x*2 rightNo = x*2+1 parentNo = x

使用方法: peek()elementadd()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;
 }
}