【leetcode】347. 前 K 个高频元素

一、题目

二、思路

/**
 * 哈希表+堆(优先队列)
 * 题目要求小于nlogn的时间,用哈希表+排序的话就是nlogn,肯定不行
 * 这里先用哈希表统计每个数字出现的次数,然后用优先队列去操作,
 * 当队列中元素个数小于k时,直接入队;
 * 队列元素个数大于k时,拿队首元素和入队元素比较,如果队首元素大于入队元素,
 * 说明当前队列所有元素都大于入队元素,直接进行下一个,如果队首元素小于入队元素,
 * 那么队首元素出队,入队元素入队即可。
 * 哈希表记录元素出现个数,每个元素O(1),n个元素O(n),
 * 堆的大小最多为k,k<=n,每次操作需要O(logk),n个元素就是O(nlogk),满足题意
 */

三、代码

public int[] topKFrequent(int[] nums, int k) {
            //统计元素出现次数
            Map<Integer, Integer> counts = new HashMap<>();
            for (int n : nums) {
                counts.put(n, counts.getOrDefault(n, 0) + 1);
            }
            //入队
            PriorityQueue<int[]> priorityQueue = new PriorityQueue<>(new Comparator<int[]>() {
                @Override
                public int compare(int[] o1, int[] o2) { //提供自定义比较器
                    return o1[1] - o2[1];
                }
            });
            for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
                int key = entry.getKey(), value = entry.getValue();
                if (priorityQueue.size() < k) { //队列不满时
                    priorityQueue.add(new int[]{key, value});
                } else { //队列满时
                    if (priorityQueue.peek()[1] < value) { //入队值比队首值大
                        priorityQueue.poll(); //队首出队
                        priorityQueue.add(new int[]{key, value}); //当前元素入队
                    }
                }
            }
            //返回结果
            int[] res = new int[k];
            for (int i = 0; i < k; i++) {
                res[i] = priorityQueue.poll()[0]; //接收的是key
            }
            return res;
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值