码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 前 K 个高频元素问题


    前 K 个高频元素问题

    作者:Grey

    原文地址: 前 K 个高频元素问题

    题目描述#

    LeetCode 347. Top K Frequent Elements

    思路#

    第一步,针对数组元素封装一个数据结构

    public class Node {
        int v;
        int t;
        public Node(int value, int times) {
            v = value;
            t = times;
        }
    }
    

    其中v表示数组元素,t表示数组元素出现的次数。

    第二步,使用哈希表把每个元素的词频先存一下。其中key是数组元素,value是Node类型,封装了数组元素和次数。

            Map<Integer, Node> freqMap = new HashMap<>();
            for (int n : arr) {
                if (freqMap.containsKey(n)) {
                    // 存在就把词频加一
                    freqMap.get(n).t++;
                } else {
                    // 不存在就新建一个词频
                    freqMap.put(n, new Node(n, 1));
                }
            }
    

    第三步,使用一个小根堆,按词频从小到大。我们需要将这个小根堆维持在K个高频元素。具体做法如下

    如果堆未超过K个元素,可以入堆;

    如果堆已经到了K个元素了,就看堆顶的元素出现的次数是否比即将要遍历的元素出现的次数少,如果堆顶元素出现的次数比即将要遍历的元素少,

    说明即将遍历的元素比堆顶元素更高频,可以替换掉堆顶元素,将其入堆;

    如果堆已经超过K个元素了,那么弹出元素,让堆始终保持在K个元素。

    第四步,弹出堆中所有元素,即为前K个高频元素。

    完整代码如下:

        public static class Node {
            // 值
            public int v;
            // 次数
            public int t;
    
            public Node(int value, int times) {
                v = value;
                t = times;
            }
        }
    
        public static int[] topKFrequent(int[] arr, int k) {
            if (arr == null || arr.length == 0 || arr.length < k) {
                return null;
            }
            Map<Integer, Node> freqMap = new HashMap<>();
            for (int n : arr) {
                if (freqMap.containsKey(n)) {
                    freqMap.get(n).t++;
                } else {
                    freqMap.put(n, new Node(n, 1));
                }
            }
            // 字符种类没有k个,无法得到结果
            if (freqMap.size() < k) {
                return null;
            }
            int[] ans = new int[k];
            PriorityQueue<Node> topK = new PriorityQueue<>(k, Comparator.comparingInt(o -> o.t));
            for (Map.Entry<Integer, Node> entry : freqMap.entrySet()) {
                if (topK.size() <= k || topK.peek().t < entry.getValue().t) {
                    topK.offer(entry.getValue());
                }
                if (topK.size() > k) {
                    topK.poll();
                }
            }
            int i = 0;
            while (!topK.isEmpty()) {
                ans[i++] = topK.poll().v;
            }
            return ans;
        }
    
    折叠

    更多#

    算法和数据结构笔记

  • 相关阅读:
    Java_GUI编程-----1、 GUI编程简介
    Java并发篇:6个必备的Java并发面试种子题目
    普中精灵开发板stm32烧录程序失败
    16-JavaSE基础巩固项目:拼图小游戏
    Cpolar+Tipas:在Ubuntu上搭建私人问答网站,为您提供专业的问题解答
    点云从入门到精通技术详解100篇-点云滤波算法及单木信息提取(续)
    【SQL server】 表结构的约束和维护
    Java算法 每日一题(六) 编号203:移除链表元素
    【Spring(六)】使用篇:AOP在开发中的使用
    nodejs+vue人脸识别考勤管理系统的设计与实现-计算机毕业设计
  • 原文地址:https://www.cnblogs.com/greyzeng/p/16469101.html
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号