【Java数据结构】前K个高频单词

前K个高频单词

692. 前K个高频单词 - 力扣(LeetCode)

解决这个问题我们先得知道每个单词出现的次数,用map存储下来,然后将出现次数最多的通过建立小根堆解决top-K问题 ,重点是top-K的求取。

1.建立map 

首先我们可以先将这些单词的出现次数都通过map中的key和value记录下来。第一步先创建一个map

Map<String, Integer> map = new HashMap<>();

2.将单词以及单词出现的次数存储到map中

在这里需要注意第一次出现的单词,第一次出现的单词没有对应的value值就会返回一个空指针null,往后再出现就直接在value中加1即可。 

       for (String word : words){
            //为什么不直接在map的基础上加1呢?原因在于第一次记录某一个单词时get(word)会返回null(Integer类型的默认值就是null),如果为空就不能进行加1的操作并且报空指针异常
            //map.put(word, map.get(word)+1);

            //方法1,可以通过map中getOrDefault方法设置它的第一次出现
            //map.put(word, map.getOrDefault(word,0)+1);

            //方法2,通过if-else,当出现为空时,那就更新value值;不为空时就加1
            if (map.get(word) == null){//如果这个单词在之前遍历时没有出现过,那就
                map.put(word, 1);
            }else{
                map.put(word, map.get(word)+1);
            }
        }

3.建立小根堆

要得到单词次数最多的前K个,就需要建立小根堆(在之前的优先级对列中已经讲过),会用到PriorityQueue。 建立小根堆需要上传一个比较器,这个比较器是将

    //建立小根堆
    PriorityQueue<Map.Entry<String, Integer>> minHeap = new PriorityQueue<>(new Comparator<Map.Entry<String, Integer>>() {
        @Override
        public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
            return o1.getValue() - o2.getValue();
        }
    });

4.遍历map,依次加入堆中

现在我们想想,要将单词加入堆中,可能会出现k大于words中所有单词的个数,这样就可以直接把所有单词都加入堆中;

if (minHeap.size() < k){
    minHeap.offer(entry);
}

剩下一种可能就是k<=words.length(),对于这个情况来说每次加入一个单词都需要进行比较,比较的情况也很多种。下面仔细的讲一下如果比较,首先我们需要知道在这个堆中的堆顶元素top,当加入的单词频率与top相同时,需要把top出队,然后让字母小的进来;还有就是可能会出现频率比top的大的情况,这种情况也需要先出队然后再进队。

        else{
        Map.Entry<String, Integer> top = minHeap.peek();
        //频率相同时,也就是出现次数相同时
         if (top.getValue().compareTo(entry.getValue()) == 0){
             //字母小的先进来
             if(top.getKey().compareTo(entry.getKey()) > 0){
                //top的单词比进来的要大,所以top要出队,entry要进队
                 minHeap.poll();
                 minHeap.offer(entry);
             }
         }else{
             //
             if(top.getValue().compareTo(entry.getValue())<0){
                 minHeap.poll();
                 minHeap.offer(entry);
             }
         }

5.依次讲堆中的单词放进List<String>类型中

 List<String>类型,所以我们需要创建一个ArrayList类型的集合用于存放堆中单词,但是题目需要的是从大到小的单词频率,从堆中拿出来的是从小到大的,所以最后还需要逆序一遍顺序表。

    List<String> ret = new ArrayList<>();
    for (int i = 0; i < k; i++){
        Map.Entry<String, Integer> top = minHeap.poll();
        ret.add(top.getKey());
    }
    Collections.reverse(ret);
    return ret;

6.改进比较器

如果把以上全部代码放到在线OJ题中,会发现总有一个结过时不通过的。那为什么呢?主要在于如果k>所有单词的个数,那么在堆中就没有相同频率的比较,所以我们还需要在比较器中添加频率相同时需要建立一个大根堆。

    PriorityQueue<Map.Entry<String, Integer>> minHeap = new PriorityQueue<>(new Comparator<Map.Entry<String, Integer>>() {
        @Override
        public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
            //当字母频率相同时,按照字母建立大根堆
            if (o1.getValue().compareTo(o2.getValue()) == 0){
                return o2.getKey().compareTo(o1.getKey());
            }
            return o1.getValue() - o2.getValue();
        }
    });

以下是全部代码,大家可以参考一下哦~

public static List<String> topKFrequent(String[] words, int k) {//
        HashMap<String, Integer> map = new HashMap<>();
        for (String word : words){
            //为什么不直接在map的基础上加1呢?原因在于第一次记录某一个单词时get(word)会返回null(Integer类型的默认值就是null),
            //如果为空就不能进行加1的操作并且报空指针异常
            //map.put(word, map.get(word)+1);

            //方法1,可以通过map中getOrDefault方法设置它的第一次出现
            //map.put(word, map.getOrDefault(word,0)+1);

            //方法2,通过if-else,当出现为空时,那就更新value值;不为空时就加1
            if (map.get(word) == null){//如果这个单词在之前遍历时没有出现过,那就
                map.put(word, 1);
            }else{
                map.put(word, map.get(word)+1);
            }
        }
    //建立小根堆
    PriorityQueue<Map.Entry<String, Integer>> minHeap = new PriorityQueue<>(new Comparator<Map.Entry<String, Integer>>() {
        @Override
        public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
            //当字母频率相同时,按照字母建立大根堆
            if (o1.getValue().compareTo(o2.getValue()) == 0){
                return o2.getKey().compareTo(o1.getKey());
            }
            return o1.getValue() - o2.getValue();
        }
    });
        //遍历map,调整优先级队列
        for(Map.Entry<String, Integer> entry : map.entrySet()){
            if (minHeap.size() < k){
                minHeap.offer(entry);
        }
        else{
        Map.Entry<String, Integer> top = minHeap.peek();
        //频率相同时,也就是出现次数相同时
         if (top.getValue().compareTo(entry.getValue()) == 0){
             //字母小的先进来
             if(top.getKey().compareTo(entry.getKey()) > 0){
                //top的单词比进来的要大,所以top要出队,entry要进队
                 minHeap.poll();
                 minHeap.offer(entry);
             }
         }else{
             //
             if(top.getValue().compareTo(entry.getValue())<0){
                 minHeap.poll();
                 minHeap.offer(entry);
             }
         }
        }
        }

    List<String> ret = new ArrayList<>();
    for (int i = 0; i < k; i++){
        Map.Entry<String, Integer> top = minHeap.poll();
        ret.add(top.getKey());
    }
    Collections.reverse(ret);
    return ret;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/982352.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

锂电池升压到5V并且可以锂电池充电的芯片SM5401

收拾旧物时发现一个旧台灯&#xff0c;正好又有一节锂电池&#xff0c;于是想改成&#xff1a;用锂电池给台灯供电&#xff08;台灯是5V的&#xff09;&#xff0c;并且可以通过USB给锂电池充电。 于是找到了SM5401这个芯片。 SM5401 可以把锂电池电压升压成5V输出&#xff0c…

大模型工程师学习日记(十五):Hugging Face 模型微调训练(基于 BERT 的中文评价情感分析)

1. datasets 库核心方法 1.1. 列出数据集 使用 d atasets 库&#xff0c;你可以轻松列出所有 Hugging Face 平台上的数据集&#xff1a; from datasets import list_datasets# 列出所有数据集 all_datasets list_datasets()print(all_datasets)1.2. 加载数据集 你可以通过 l…

高考數學。。。

2024上 具体来说&#xff0c;直线的参数方程可以写为&#xff1a; x1t y−t z1t 二、简答题(本大题共5小题&#xff0c;每小题7分&#xff0c;共35分。) 12.数学学习评价不仅要关注结果评价&#xff0c;也要关注过程评价。简要说明过程评价应关注哪几个方面。…

Seurat - Guided Clustering Tutorial官方文档学习及复现

由于本人没有使用过Seurat4.0&#xff0c;而是直接使用的最新版。所以本文都是基于Seurat5.2.0&#xff08;截止2025/3/6&#xff09;来进行撰写。 参考的官方教程来进行学习&#xff08;上图中的 Guided tutorial-2.700 PBMCs&#xff09;&#xff0c;肯定没有官方文档那么全面…

(undone) MIT6.S081 Lec14 File systems 学习笔记

url: https://mit-public-courses-cn-translatio.gitbook.io/mit6-s081/lec14-file-systems-frans Why Interesting 从一个问题开始&#xff1a;既然你每天都使用了文件系统&#xff0c;XV6的文件系统与你正在使用的文件系统有什么区别。接下来我会点名&#xff1a; 学生回答…

【C++进阶学习】第一讲——继承(下)---深入挖掘继承的奥秘

目录 1.隐藏 1.1隐藏的概念 1.2隐藏的两种方式 2.继承与友元 3、继承与静态成员 4.单继承和多继承 4.1单继承 4.2多继承 5.菱形继承 问题1&#xff1a;冗余性 问题2&#xff1a;二义性 6.虚拟继承 7.总结 1.隐藏 1.1隐藏的概念 在 C 中&#xff0c;继承是一种机制…

UI自动化:利用百度ocr识别解决图形验证码登录问题

相信大家在做自动化测试过程中都遇到过图形验证码的问题&#xff0c;最近我也是遇到了&#xff0c;网上搜了很多方法&#xff0c;最简单的方法无非就是去掉图形验证码或者设置一个万能验证码&#xff0c;但是这个都需要开发来帮忙解决&#xff0c;对于我们这种自学的人来说就不…

C/C++蓝桥杯算法真题打卡(Day1)

一、LCR 018. 验证回文串 - 力扣&#xff08;LeetCode&#xff09; 算法代码&#xff1a; class Solution { public:bool isPalindrome(string s) {int n s.size();// 处理一下s为空字符的情况if (n 0) {return true; // 修正拼写错误}// 定义左右指针遍历字符串int left …

蓝桥杯备考:动态规划路径类DP之矩阵的最小路径和

如题&#xff0c;要求左上角到右下角的最短路径&#xff0c;我们还是老样子按顺序做 step1:确定状态表示 f[i][j]表示(1,1)到(i,j)的最短距离 step2 :推导状态表达方程 step3:确定填表顺序&#xff0c;应该是从上到下&#xff0c;从左到右 step4:初始化 step5 找结果&#…

18类创新平台培育入库!长沙经开区2025年各类科技创新平台培育申报流程时间材料及申报条件

长沙经开区打算申报企业研发中心、技术创新中心、工程技术研究中心、新型研发机构、重点实验室、概念验证中心和中试平台、工程研究中心、企业技术中心、制造业创新中心、工业设计中心等创新平台的可先备案培育入库&#xff0c;2025年各类平台的认定将从培育库中优先推荐&#…

CyberDefenders----WebStrike Lab

WebStrike Lab 实验室链接 简介: 公司网络服务器上发现了一个可疑文件,在内联网中发出警报。开发团队标记了异常,怀疑存在潜在的恶意活动。为了解决这个问题,网络团队捕获了关键网络流量并准备了一个 PCAP 文件以供审查。您的任务是分析提供的 PCAP 文件以发现文件的出现…

【python】gunicorn配置

起因&#xff1a;因为cpu利用率低导致我去缩容&#xff0c;虽然缩容之后cpu利用率上升维持在60%左右&#xff0c;但是程序响应耗时增加了。 解释&#xff1a;因为cpu干这件活本身不累&#xff0c;但在干这件活的时候不能去干其他事情&#xff0c;导致并发的请求不能及时响应&am…

SSE vs WebSocket:AI 驱动的实时通信抉择

引言 近年来,基于 Transformer 的大模型推动了 AI 产业的飞速发展,同时带来了新的技术挑战: 流式传输 vs 批量返回:大模型生成的长文本若需一次性返回,会显著影响用户体验,实时推送成为必需。语音交互需求:语音助手要求毫秒级响应,而非等待用户完整输入后再返回结果。…

基于海思soc的智能产品开发(芯片sdk和linux开发关系)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 随着国产化芯片的推进&#xff0c;在soc领域&#xff0c;越来越多的项目使用国产soc芯片。这些soc芯片&#xff0c;通常来说运行的os不是linux&…

各种DCC软件使用Datasmith导入UE教程

3Dmax: 先安装插件 https://www.unrealengine.com/zh-CN/datasmith/plugins 左上角导出即可 虚幻中勾选3个插件,重启引擎 左上角选择文件导入即可 Blender导入Datasmith进UE 需要两个插件, 文章最下方链接进去下载安装即可 一样的,直接导出,然后UE导入即可 C4D 直接保存成…

VMware Fusion虚拟机Mac版安装Ubuntu系统

介绍 Ubuntu操作系统是一个基于Linux内核的桌面和服务器操作系统。它由Canonical公司开发和维护&#xff0c;是最受欢迎的Linux操作系统之一。Ubuntu操作系统以简洁、直观和易用为设计原则&#xff0c;提供了友好的图形界面&#xff0c;支持多种语言和自定义设置&#xff0c;用…

发行思考:全球热销榜的频繁变动

几点杂感&#xff1a; 1、单机游戏销量与在线人数的衰退是剧烈的&#xff0c;有明显的周期性&#xff0c;而在线游戏则稳定很多。 如去年的某明星游戏&#xff0c;最高200多万在线&#xff0c;如今在线人数是48名&#xff0c;3万多。 而近期热门的是MH&#xff0c;在线人数8…

AI赋能科研绘图与数据可视化高级应用

在科研成果竞争日益激烈的当下&#xff0c;「一图胜千言」已成为高水平SCI期刊的硬性门槛——数据显示很多情况的拒稿与图表质量直接相关。科研人员普遍面临的工具效率低、设计规范缺失、多维数据呈现难等痛点&#xff0c;因此科研绘图已成为成果撰写中的至关重要的一个环节&am…

thingsboard edge 在windows 环境下的配置

按照官方文档&#xff1a;Installing ThingsBoard Edge on Windows | ThingsBoard Edge&#xff0c;配置好java环境和PostgreSQL。 下载对应的windows 环境下的tb-edge安装包。下载附件 接下来操作具体如下 步骤1&#xff0c;需要先在thingsboard 服务上开启edge 权限 步骤2…

最硬核DNS详解

1、是什么 DNS&#xff08;域名系统&#xff09;是互联网的一项服务&#xff0c;它作为将域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使人更方便地访问互联网。DNS协议基于UDP协议&#xff0c;使用端口号53。 2、域名服务器类型 域名服务器在DNS体系中扮演着不…