LeetCodeHot100 347. 前 K 个高频元素

题目

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

**输入:**nums = 1,1,1,2,2,3, k = 2

输出:1,2

示例 2:

**输入:**nums = 1, k = 1

输出:1

示例 3:

**输入:**nums = 1,2,1,2,1,2,3,1,3,2, k = 2

输出:1,2

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104
  • k 的取值范围是 [1, 数组中不相同的元素的个数]
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

进阶: 你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n是数组大小。

思路解析

思路很简单,维护一个最小堆,这个堆大小为k,以元素的出现次数排序,达到k后看堆顶的元素次数进行对比然后判断是否移出去。

详细代码与注释

java 复制代码
class Solution {

    public int[] topKFrequent(int[] nums, int k) {

        /* =====================================================
         * 一、统计每个数字出现的次数
         * ===================================================== */

        // HashMap:key 是数字本身,value 是该数字出现的次数
        Map<Integer, Integer> count = new HashMap<>();

        // 遍历数组 nums
        for (int num : nums) {
            /*
             * count.getOrDefault(num, 0)
             * 如果 map 中已经存在 num,则返回 num 对应的次数
             * 如果 map 中不存在 num,则返回默认值 0
             */
            count.put(num, count.getOrDefault(num, 0) + 1);
        }

        /* =====================================================
         * 二、创建一个小顶堆(按出现次数排序)
         * ===================================================== */

        /*
         * PriorityQueue<int[]>:
         * 堆中存放的是 int 数组
         * 约定数组结构:
         *   arr[0] = 数字
         *   arr[1] = 该数字出现的次数
         */
        PriorityQueue<int[]> queue = new PriorityQueue<>(
            new Comparator<int[]>() {
                @Override
                public int compare(int[] o1, int[] o2) {
                    /*
                     * 比较规则:按出现次数升序排序
                     * o1[1] - o2[1] < 0  → o1 优先
                     * 因此这是一个「小顶堆」
                     */
                    return o1[1] - o2[1];
                }
            }
        );

        /* =====================================================
         * 三、遍历 HashMap,把前 k 个高频元素放入堆中
         * ===================================================== */

        // 遍历 Map 中的每一对 (数字, 出现次数)
        for (Map.Entry<Integer, Integer> entry : count.entrySet()) {

            // 当前数字
            int num = entry.getKey();

            // 当前数字出现的次数
            int freq = entry.getValue();

            // 如果堆的大小已经等于 k,说明堆满了
            if (queue.size() == k) {

                /*
                 * peek() 查看堆顶元素(不删除)
                 * 由于是小顶堆,堆顶元素的出现次数是当前堆中最小的
                 */
                if (queue.peek()[1] < freq) {
                    // 当前数字出现次数更大,应该进入前 k

                    // 删除堆顶(出现次数最小的那个)
                    queue.poll();

                    // 把当前数字及其出现次数加入堆中
                    queue.offer(new int[]{num, freq});
                }

                // 如果当前频率 <= 堆顶频率
                // 说明排不进前 k,直接跳过

            } else {
                // 如果堆还没满 k 个元素,直接加入
                queue.offer(new int[]{num, freq});
            }
        }

        /* =====================================================
         * 四、从堆中取出结果
         * ===================================================== */

        // 结果数组,长度为 k
        int[] res = new int[k];

        // 依次从堆中取出元素
        for (int i = 0; i < k; i++) {
            /*
             * poll() 会取出并删除堆顶元素
             * 堆中存的是 [数字, 出现次数]
             * 我们只需要数字,所以取下标 0
             */
            res[i] = queue.poll()[0];
        }

        // 返回前 k 个高频元素
        return res;
    }
}
相关推荐
mldong3 小时前
弃用 ZCode,转 DeepSeek Harness:我用 GitHub Actions 自建 Windows 打包的全实录
java·架构
AgentMaster3 小时前
数据资产化落地难题:5款数据中台系统架构对比与实施记录
大数据·人工智能·算法
Wang's Blog3 小时前
Java 接入Redis: Redis下载与源码编译安装
java·服务器·redis
农民工老王4 小时前
故障排查:反向代理转发 GET 请求时 JDK 自动追加 Content-Length:0 致后端 500
java·httpclient·content-length
泡海椒4 小时前
jquick-pdf 防止 PDF 内容分页断裂:keepTogether 属性妙用
java·开发语言·pdf
vx_BS813304 小时前
【项目编号:project51381】Spring Boot 婚纱摄影管理系统:套餐预约、在线咨询、支付与客片展示的一站式业务实现
java·spring boot·eclipse·tomcat·mybatis
IT毕设实战小研4 小时前
基于大数据的商场商铺数据分析与可视化的设计与实现
android·java·大数据·django·课程设计
万年咸鱼4 小时前
Java Classpath 详解:从原理到实战
java
鹿角片ljp4 小时前
从 Kimi Cyber Reasoning 学习网络安全推理数据集:从 Reasoning SFT 到安全 Agent 数据设计
数据结构·算法
Ivanqhz4 小时前
矩阵引擎的数据流模式与 BM1684X 架构
java·服务器·网络·深度学习·神经网络