Leetcode 347-前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
在这里插入图片描述
在这里插入图片描述
进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。

题解

在这里,我们可以利用堆的思想:建立一个小顶堆,然后遍历「出现次数数组」:

如果堆的元素个数小于 k,就可以直接插入堆中。
如果堆的元素个数等于 k,则检查堆顶与当前出现次数的大小。如果堆顶更大,说明至少有 k 个数字的出现次数比当前值大,故舍弃当前值;否则,就弹出堆顶,并将当前值插入堆中。
遍历完成后,堆中的元素就代表了「出现次数数组」中前 k 大的值。

/*
借助 哈希表 来建立数字和其出现次数的映射,遍历一遍数组统计元素的频率
维护一个元素数目为 k 的最小堆
每次都将新的元素与堆顶元素(堆中频率最小的元素)进行比较
如果新的元素的频率比堆顶端的元素大,则弹出堆顶端的元素,将新的元素添加进堆中
最终,堆中的 k 个元素即为前 k 个高频元素

作者:程序员吴师兄
链接:https://leetcode.cn/problems/top-k-frequent-elements/solutions/11201/leetcode-di-347-hao-wen-ti-qian-k-ge-gao-pin-yuan-/
*/
//remove()、add()、peek()、size()
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        // 使用字典,统计每个元素出现的次数,元素为键,元素出现的次数为值
        HashMap<Integer,Integer> map = new HashMap();
        for(int num : nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        //堆的构造函数
        PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){
            @Override
            //注意这里是Integer而不是int
            public int compare(Integer a,Integer b){
                return map.get(a)-map.get(b);
            }
        });

        // 遍历map,用最小堆保存频率最大的k个元素
        for(Integer key:map.keySet()){
            //还未形成堆
            if(pq.size()<k){
                pq.add(key);
            }else{
                if(map.get(pq.peek())<map.get(key)){
                    pq.remove();
                    pq.add(key);
                }
            }
        }

        // 取出最小堆中的元素
        int res[] = new int[k];
        int i=0;
        while(!pq.isEmpty()){
            res[i++]=pq.remove();
        }

        return res;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值