力扣记录:栈与队列7——347 前 K 个高频元素

该博客详细介绍了如何利用Java的优先级队列(PriorityQueue)来查找整数数组中出现频率最高的前K个元素。通过创建一个Map存储每个元素的频次,然后构建一个小顶堆,不断比较新元素与堆顶元素的频率,当堆大小达到K时,保持堆中始终为最高频次的元素。最终堆中剩余的K个元素即为所求。这种方法有效地实现了高效查找高频元素的目标。
摘要由CSDN通过智能技术生成

本次题目

  • 347 前 K 个高频元素

347 前 K 个高频元素

  • 队列:使用Map实现优先级队列(跟堆相同,队列内部有序排列,头部是最大值为大顶堆,头部为最小值为小顶堆)。
    1. 这里使用小顶堆(定义时构造大小对比方法),先使用Map存储数组中的数及其出现次数,然后将Map中元素依次压入小堆栈。
    2. 当顶堆的大小等于要求的k时,压入元素时与堆顶元素进行判断,若小于堆顶则不操作,若大于堆顶,则将堆顶元素弹出,压入新元素。
    3. 最后,顶堆中剩下的k个元素为频率最高的元素(弹出倒序)。
  • 注意:PriorityQueue大顶堆右大于左,小顶堆左大于右。使用entrySet遍历Map获取键值对(keySet和values分别只获取键和值)。
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        //先使用Map存储数组中的数及其出现次数
        Map<Integer, Integer> map = new HashMap<>();
        //遍历数组
        for(int i : nums){
            if(!map.containsKey(i)){
                map.put(i, 0);
            }
            map.put(i, map.get(i) + 1);
        }
        //定义数组存储结果
        int[] res = new int[k];
        //定义小顶堆并构造大小对比方法
        PriorityQueue<Map.Entry<Integer, Integer>> priQueue = new PriorityQueue<>((o1, o2) -> o1.getValue() - o2.getValue());
        //遍历Map并压入元素
        for(Map.Entry<Integer, Integer> entry : map.entrySet()){
            //当顶堆的大小等于要求的k时,压入元素时与堆顶元素进行判断
            if(priQueue.size() >= k){
                //若大于堆顶,则将堆顶元素弹出,压入新元素
                //若小于堆顶则不操作
                if(entry.getValue() > priQueue.peek().getValue()){
                    priQueue.poll();
                    priQueue.offer(entry);
                }
            }else{//否则直接压入
                priQueue.offer(entry);
            }
        }
        //最后,顶堆中剩下的k个元素为频率最高的元素(弹出倒序)
        for(int i = k - 1; i >= 0; i--){
            res[i] = priQueue.poll().getKey();
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值