算法题目:前 K 个高频元素

思路:先循环整个数组,将数组中的元素和元素出现的次数存hashmap的集合中,在循环集合,建立一个有优先队列PriorityQueue,优先队列的长度为k,当长度还未到达k的时候直接将数据放入优先队列中,优先队列长度为k时,比较优先队列顶部的元素大小,当元素大于队列顶部元素时,取出顶部元素并将当前元素放入队列中。

优先队列(PriorityQueue):具体是通过完成二叉树实现,小顶堆保证每个节点的值都小于等于其两个子节点,顶部则是最小值,大顶堆则相反。本题使用的是大顶堆,需要重写比较器Comparator。

代码如下:

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        int[] res = new int[k];
        Map<Integer, Integer> numsMap = new HashMap<>(nums.length);
        //遍历数组将数组,出去重复字段,并且将元素及元素出现的次数存入hashmap集合中
        for(int i : nums) {
            Integer num = numsMap.getOrDefault(i, 0);
            numsMap.put(i, ++num);
        }
        //优先队列需要重现比较器。这里重写了比较器实现了大顶堆
        PriorityQueue<Map<Integer, Integer>> priorityQueue = new PriorityQueue<>(new Comparator<Map<Integer, Integer>>() {
            @Override
            public int compare(Map<Integer, Integer> o1, Map<Integer, Integer> o2) {
                return o1.get("val") - o2.get("val");
            }
        });
        //lamda表达式,我在力扣提交代码的时候报错了,上面那段代码没问题,可能是力扣不支持。
        /*PriorityQueue<Map<Integer, Integer>> priorityQueue = new PriorityQueue<Map<Integer, Integer>>(((o1, o2) -> {
            return o1.get("val") - o2.get("val");
        }));*/
        //循环hashmap集合
        for(Map.Entry<Integer, Integer> e : numsMap.entrySet()) {
            int key = e.getKey();
            int val = e.getValue();
            //当队列元素不足k时,直接放入队列中
            if(priorityQueue.size() < k) {
                priorityQueue.add(new HashMap(2) {
                    {
                        put("key", key);
                        put("val", val);
                    }
                });
            } else {
                //当队列已经满员,则先比较顶部元素和当前元素的大小,如果顶部元素小于当前元素则将顶部元素取出,然后放入当前元素
                if(priorityQueue.peek().get("val") < val ) {
                    priorityQueue.poll();
                    priorityQueue.add(new HashMap(2) {
                        {
                            put("key", key);
                            put("val", val);
                        }
                    });
                }
            }
        }
        //循环优先队列,将队列中的元素放入返回值中
        for(int i = 0; !priorityQueue.isEmpty(); i++) {
            res[i] = priorityQueue.poll().get("key");
        }
        return res;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值