leetcode-中等题-347. 前 K 个高频元素

JAVA优先级队列元素输出顺序测试
Java @Override的作用(重写需要注意的 注释)
Java中PriorityQueue的排序
挺难的,主要要了解优先队列用法,重写用法,堆的原理。
优秀解答1:

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        //设置一个map集合,key存放数字,value存放出现次数
        Map<Integer,Integer> map = new HashMap<>();
        //统计出现次数
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        //建立一个小根堆,用来存放key值,堆内元素按照key对应的value值从小到大排序
        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){
            public int compare(Integer a,Integer b){
                return map.get(a) - map.get(b);
            }
        });
        //将map中的数字,插入到大根堆中
        for(Integer key:map.keySet()){
            if(queue.size() < k){
                queue.add(key);
            }else if(map.get(key) > map.get(queue.peek())){
                queue.poll();
                queue.add(key);
            }
        }
        //将大根堆中的k个数字放到数组中
        int [] res = new int[k];
        int index = 0;
        while(!queue.isEmpty()){
            res[index++] = queue.poll();
        }
        return res;
    }
}

优秀解答2:

class Solution {
    public List<Integer> topKFrequent(int[] nums, int k) {
        // 使用字典,统计每个元素出现的次数,元素为键,元素出现的次数为值
        HashMap<Integer,Integer> map = new HashMap();
        for(int num : nums){
            if (map.containsKey(num)) {
               map.put(num, map.get(num) + 1);
             } else {
                map.put(num, 1);
             }
        }
        // 遍历map,用最小堆保存频率最大的k个元素
        PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer a, Integer b) {
                return map.get(a) - map.get(b);
            }
        });
        for (Integer key : map.keySet()) {
            if (pq.size() < k) {
                pq.add(key);
            } else if (map.get(key) > map.get(pq.peek())) {
                pq.remove();
                pq.add(key);
            }
        }
        // 取出最小堆中的元素
        List<Integer> res = new ArrayList<>();
        while (!pq.isEmpty()) {
            res.add(pq.remove());
        }
        return res;
    }
}


作者:cxywushixiong
链接:https://leetcode-cn.com/problems/top-k-frequent-elements/solution/leetcode-di-347-hao-wen-ti-qian-k-ge-gao-pin-yuan-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我的解法:

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        //1.hashmap来统计频次
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            if(map.containsKey(nums[i])){
                map.put(nums[i], map.get(nums[i])+1);
            }
            else{
                map.put(nums[i],1);
            }
        }
        //2.优先队列放入前k频次的数,原理是小根堆  (需要重写Override优先队列的排序方法)
        Comparator<Integer> cmp = new Comparator<>(){
            @Override
            public int compare(Integer a, Integer b){
                return map.get(a) - map.get(b);
            }
        };
        PriorityQueue<Integer> pq = new PriorityQueue<>(cmp);//cmp指定由value的小到大排序,越小越靠前
        for(Integer key : map.keySet()){
            if(pq.size() < k) pq.add(key);
            else if(map.get(key) > map.get(pq.peek())){
                pq.poll();//把对头小频次的key出列
                pq.add(key);
            }
        }
        System.out.println(pq);
        //3.输出前k个数
        int[] res = new int[pq.size()];
        int size = pq.size();//注意size会变化,不要写到循环里面
        for(int i = 0; i < size; i++){
            res[i] = pq.poll();
        }
        return res;
    }
}

你可能感兴趣的:(leetcode,算法)