前k个高频单词

news2025/1/13 13:44:40

💕**不要害怕前方的未知和困难,因为它们都是你成长的机会。不要过于在意别人的眼光和评价,因为唯有你的内心才知道自己真正的价值。珍惜当下,享受生活的点滴,让自己变得更加坚强、自信、成熟。**💕
🐼作者:不能再留遗憾了🐼
🎆专栏:Java学习🎆
🚗本文章主要内容:前k个高频单词 题解🚗
在这里插入图片描述

文章目录

  • 题目要求
  • 做题思路
  • 代码实现
    • 统计单词出现的次数
    • 创建大小为k的最小堆
    • 修改构造器
    • 将最小堆的数据插入到顺序表中并逆序
  • 整体代码展示

leetcode之前k个高频单词(难度:中等)

题目要求

给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。

示例 1:

输入: words = [“i”, “love”, “leetcode”, “i”, “love”, “coding”], k = 2
输出: [“i”, “love”] 解析: “i” 和 “love” 为出现次数最多的两个单词,均为2次。
注意,按字母顺序 “i” 在 “love” 之前。

示例 2:

输入: [“the”, “day”, “is”, “sunny”, “the”, “the”, “the”, “sunny”, “is”,
“is”], k = 4 输出: [“the”, “is”, “sunny”, “day”] 解析: “the”, “is”,
“sunny” 和 “day” 是出现次数最多的四个单词,
出现次数依次为 4, 3, 2 和 1 次。

class Solution {
    public List<String> topKFrequent(String[] words, int k) {

    }
}

做题思路

首先,当我们看到题目TopK的问题时,就会想到使用堆来解决,如果大家不了解堆,可以看看我的这篇文章什么是堆以及堆是怎样创建的。如果TopK是前K个最大的值,那么就需要使用构建最小堆来解决,如果TopK是前K个最小的值,那么就需要构建最大堆来解决。很显然这道题是求前K个高频单词,所以我们构建最小堆来解决问题。

在知道了使用什么结构来解决,我们还需要知道,怎样才能知道每个单词出现的次数呢?很多人第一想法可能是通过创建一个类来实现,类里面有这个单词以及单词出现的次数,但是太麻烦了,不推荐。那么怎样做才最简单呢?那就是使用我们的HashMap的Key — Value模型,将单词作为Key,次数作为Value

在统计完每个单词出现的次数之后,我们就创建k个大小的最小堆,每次进堆就与最小堆的根节点所代表的单词出现的次数比较,如果待进堆的单词出现的次数大于堆的根节点单词出现的次数,那么就先出堆,然后再将待插入的数据入堆,调整最小堆。

当HashMap中的数据都遍历完成后,我们就需要将最小堆中的k个数据出堆,我们都知道每次从最小堆中出来的都是堆顶的也就是堆中最小的数据,但是我们再仔细看题目要求可以知道按单词出现的频率的高低排序。所以我们需要先将HashMap中的数据都插入到一个顺序表中,然后再将整个顺序表逆序一次就得到了我们想要的结果。

在这里插入图片描述

代码实现

统计单词出现的次数

	Map<String,Integer> hashmap = new HashMap<>();
    for(String s : words) {
        if(hashmap.get(s) == null) {
            hashmap.put(s,1);
        }else {
            hashmap.put(s,hasnmap.get(s) + 1);
        }
    }

创建大小为k的最小堆

因为Java提供的PriorityQueue默认是最小堆,所以我们可以直接使用Java提供的方法。先将k个数据放入最小堆中,后面再放入数据的时候,需要比较待插入的单词出现的次数与堆顶单词出现次数的大小,如果待插入的单词出现的次数大于堆顶单词出现的数据,那么就先出堆,然后再将这个单词入堆;如果待插入单词出现的次数等于堆顶单词出现的次数,那么就需要比较带插入单词与堆顶单词的字典顺序了,如果待插入单词的字典顺序在前面,那么就先出堆然后再入堆,反之就不需要对对做出调整。

//创建k个大小的最小堆

//我们这里传入一个比较器并重写compare方法,因为Java提供的compare方法的比较是基本数据类型之间的
PriorityQueue<Map.Entry<String,Integer>> minHeap = new PriorityQueue<>(
            k,new Comparator<Map.Entry<String, Integer>>() {
                @Override
                public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                        return o1.getValue().compareTo(o2.getValue());
                    }
                }
        );

for(Map.Entry<String,Integer>  entry: hashmap.entrySet()) {
    //先在堆中存放k个节点
    if(minHeap.size() < k) {
        minHeap.offer(entry);
    }else {
      	if(minHeap.peek().getValue().compareTo(entry.getValue()) < 0) {
        	minHeap.poll();
            minHeap.offer(entry);
        }else if(minHeap.peek().getValue().compareTo(entry.getValue()) == 0) {
            //当出现的次数相同时就比较单词的字典顺序
         	if(minHeap.peek().getKey().compareTo(entry.getKey()) > 0) {
                minHeap.poll();
            	minHeap.offer(entry);
        	}
     	}
    }
}

这里我们的比较器构造的有问题,我们先看会出现什么问题
在这里插入图片描述
当k为3的时候为什么会出错呢
在这里插入图片描述
所以我们的构造器还需要添加一个条件,当单词出现的次数相同时就比较单词出现的字典顺序。

修改构造器

//创建k个大小的最小堆

//我们这里传入一个比较器并重写compare方法,因为Java提供的compare方法的比较是基本数据类型之间的
PriorityQueue<Map.Entry<String,Integer>> minHeap = new PriorityQueue<>(
            k,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().compareTo(o2.getValue());
                    }
                }
        );

for(Map.Entry<String,Integer>  entry: hashmap.entrySet()) {
    //先在堆中存放k个节点
    if(minHeap.size() < k) {
        minHeap.offer(entry);
    }else {
      	if(minHeap.peek().getValue().compareTo(entry.getValue()) < 0) {
        	minHeap.poll();
            minHeap.offer(entry);
        }else if(minHeap.peek().getValue().compareTo(entry.getValue()) == 0) {
            //当出现的次数相同时就比较单词的字典顺序
         	if(minHeap.peek().getKey().compareTo(entry.getKey()) > 0) {
                minHeap.poll();
            	minHeap.offer(entry);
        	}
     	}
    }
}

将最小堆的数据插入到顺序表中并逆序

List<String> list = new ArrayList<>();
        //3.将堆中的数据放入数组中
for(int i = 0; i < k; i++) {
    String ret = minHeap.poll().getKey();
    list.add(ret);
}

//List继承自collections类,collections类中实现了reverse逆序方法
Collections.reverse(list);

return list;

整体代码展示

class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        //1.统计每个单词出现的次数
        Map<String,Integer> hashmap = new HashMap<>();
        for(String s : words) {
            if(hashmap.get(s) == null) {
                hashmap.put(s,1);
            }else {
                hashmap.put(s,hashmap.get(s) + 1);
            }
        }

        //创建k个大小的最小堆

        //这里记得重写compare方法
        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().compareTo(o2.getValue());
                    }
                }
        );

        for(Map.Entry<String,Integer>  entry: hashmap.entrySet()) {
            //先在堆中存放k个节点
            if(minHeap.size() < k) {
                minHeap.offer(entry);
            }else {
                if(minHeap.peek().getValue().compareTo(entry.getValue()) < 0) {
                    minHeap.poll();
                    minHeap.offer(entry);
                }else if(minHeap.peek().getValue().compareTo(entry.getValue()) == 0) {
                    //当出现的次数相同时就比较单词的字典顺序
                    if(minHeap.peek().getKey().compareTo(entry.getKey()) > 0) {
                        minHeap.poll();
                        minHeap.offer(entry);
                    }
                }
            }
        }

        List<String> list = new ArrayList<>();
        //3.将堆中的数据放入数组中
        for(int i = 0; i < k; i++) {
            String ret = minHeap.poll().getKey();
            list.add(ret);
        }

        Collections.reverse(list);

        return list;
    }
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LG Gram 14 (14Z90N) 电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网&#xff0c;转载需注明出处。&#xff08;下载请直接百度黑果魏叔&#xff09; 硬件型号驱动情况 主板LG Gram 14 (14Z90N) 处理器Intel Core i5-1035G4已驱动 内存M471A1G44AB0-CWE * 2已驱动 硬盘MTFDHBA512TDV-1AZ1AABYY已驱动 显卡Intel Iris …

Axel – 用于 Linux 的命令行文件下载加速器

动动发财的小手&#xff0c;点个赞吧&#xff01; 如果您是那种喜欢下载和试用多个 Linux 发行版的人&#xff0c;我们相信您会张开双臂欢迎一个说到做到的下载加速器——一个按照其描述进行操作的下载加速器。 在本指南[1]中&#xff0c;我们将向您介绍 Axel&#xff0c;这是一…

由浅入深Dubbo核心源码剖析高可用集群

目录 1 服务集群的概述1.1 概述1.2 调用过程1.3 组件介绍 2 集群容错机制2.1 内置集群容错策略2.2 集群容错调优2.3 源码分析 3 集群负载均衡策略3.1 负载均衡的主要作用3.2 内置的负载均衡策略3.3 负载均衡总结 4 服务治理4.1 服务治理的概述4.2 执行过程4.3 服务治理功能 1 服…

由浅入深Dubbo核心源码剖析服务暴露与发现

目录 1 概述2 Spring中自定义Schema2.1 案例使用2.2 dubbo中的相关对象 3 服务暴露机制3.1 术语解释3.2 流程机制3.3 源码分析3.4 总结 4 服务发现4.1 服务发现流程4.2 源码分析4.3 总结 1 概述 dubbo是一个简单易用的RPC框架&#xff0c;通过简单的提供者&#xff0c;消费者配…

《深入理解Java虚拟机》Java虚拟机的监控及诊断工具相关命令行

《深入理解Java虚拟机》Java虚拟机的监控及诊断工具相关命令行 1.jps 查看当前系统正在运行的java进程 相关参数 -l 打印模块名以及包名 -v 打印虚拟机相关参数 -m 打印传给主类的参数 -mlv 以上内容都打印 2.jstat 打印目标 Java 进程的性能数据 -gc 打印gc回收相关信息…

基于ResNet-18实现Cifar-10图像分类

目录 1、作者介绍2、数据集介绍2.1Cifar-10数据集介绍&#xff1a; 3、ResNet网络介绍3.1Residual Network残差网络3.2ResNet18网络结构 4、代码复现及实验结果4.1训练代码4.2测试代码4.3实验结果 1、作者介绍 安耀辉&#xff0c;男&#xff0c;西安工程大学电子信息学院&…

144 Tops,特斯拉如何低成本实现了城市NOA?

作者 | 树人 编辑 | 德新 根据特斯拉2022年Q4的财务文件披露&#xff1a;FSD Beta已有将近40万用户。 这是目前全世界部署规模最大的城市NOA系统。 而特斯拉实现这样一套系统&#xff0c;在车端几乎仅用了8个摄像头和144 Tops算力的FSD计算平台。这种性能压榨和成本控制能力让…

2023年内网穿透常用的几个工具

作为一名开发者&#xff0c;先给大家普及一下什么是内网&#xff0c;什么是外网。 所谓内网就是内部建立的局域网络或办公网络。比如一家公司或一个家庭有多台计算机&#xff0c;他们利用不同网络布局将这一台或多台计算机或其它设备连接起来构成一个局部的办公或者资源共享网…

这可能是最全面的Java面试八股文了

Java的特点 Java是一门面向对象的编程语言。面向对象和面向过程的区别参考下一个问题。 Java具有平台独立性和移植性。 Java有一句口号&#xff1a;Write once, run anywhere&#xff0c;一次编写、到处运行。这也是Java的魅力所在。而实现这种特性的正是Java虚拟机JVM。已编…

2024王道数据结构考研丨第五篇:树、图

2024王道数据结构考研笔记专栏将持续更新&#xff0c;欢迎 点此 收藏&#xff0c;共同交流学习… 文章目录 第五章&#xff1a;树5.1树的基本概念5.1.1树的定义5.1.2基本术语5.1.3树的性质 5.2二叉树的概念5.2.1 二叉树的定义与特性5.2.2几种特殊的二叉树5.2.3二叉树的存储结构…

2022级云曦实验室考试(一)reverse

一.Reverse 打开后是个rar压缩包&#xff0c;解压后 发现这玩意儿&#xff0c;我也不知道是个啥&#xff0c;之前没做过这类题 浅搜一下 啊&#xff0c;看不懂 用一下自己的歪办法 用txt打开看看有没有啥&#xff1f; 发现两个里面都有相同的flag&#xff0c;改成正确格式&…

C语言小游戏--三子棋

目录 问题描述 逻辑分析 具体实现 1.进入菜单界面 2.初始化棋盘 3.打印棋盘 4.玩家下棋 5.电脑下棋 6.判断输赢 运行结果 完整代码 game.h game.c test.c 问题描述 结合C语言所学知识&#xff0c;简单实现一个三子棋小游戏。 逻辑分析 进入菜单界面初始化棋盘…

帅地这些年看过的书

大家好&#xff0c;我是帅地。 好久没有给大家推荐书籍了&#xff0c;我一般很少给大家推荐书籍&#xff0c;因为自己没看过的&#xff0c;基本不推&#xff0c;只推荐我自己看过且自己自认为不错的书籍。 因为我自己本身是凭借着扎实的基础拿到大厂 offer 的&#xff0c;所以…

nodej+vues汽车销售4s店服务平台商城系统购物车积分兑换7z9d2

在经济快速发展的带动下&#xff0c;汽车服务平台的发展也是越来越快速。用户对汽车服务信息的获取需求很大。在互联网飞速发展的今天&#xff0c;制作一个汽车服务平台系统是非常必要的。本系统是借鉴其他人的开发基础上&#xff0c;用MySQL数据库和nodejs定制了汽车服务平台系…

Windows安装多个Mysql服务

1、正常安装好第一个 正常安装即可 2、第二个安装方法 1、官网下载zip包 MySQL :: MySQL Downloads 2、解压下载好的压缩包 &#xff08;注意修改文件夹名称&#xff0c;此时文件夹内并没有data文件夹&#xff09; 3、编写my.ini 注意修改端口号port以及安装目录basedir…

龙芯2K1000实战开发-平台介绍

文章目录 概要整体架构流程技术名词解释技术细节小结概要 龙芯 2K1000 处理器主要面向于网络应用,兼顾平板应用及工控领域应 用。采用 40nm 工艺,片内集成 2 个 GS264 处理器核,主频 1GHz,64 位 DDR3 控制器,以及各种系统 IO 接口。 整体架构 龙芯 2K1000 的结构如图 所…

《Oracle高级数据库》期末复习一文总结

文章目录 第一章&#xff1a;数据库基础1.数据库系统数据库数据库管理系统数据库系统 2.数据模型层次模型网状模型关系模型 3.关系型数据库&#xff08;1&#xff09;数据定义语言&#xff08;DDL&#xff09;&#xff08;2&#xff09;数据操纵语言&#xff08;DML&#xff09…

UC-OWOD: Unknown-Classified Open World Object Detection(论文翻译)

文章目录 UC-OWOD: Unknown-Classified Open World Object Detection摘要1.介绍2.相关工作3.未知分类的开放世界目标检测3.1 问题定义3.2 整体架构3.3 未知物体的检测3.4基于相似性的未知分类3.5未知聚类优化3.6训练和优化 4&#xff1a;实验4.1准备工作4.2结果和分析4.3消融研…

数学算法组合与排序

一句话总结&#xff1a;组合得次序是否重要&#xff0c;是否可重复&#xff0c;决定了组合数量 一、什么是组合&排序 组合可以是现实的一切事物、例如 [衣服&#xff0c;鞋子&#xff0c;眼镜...] 等等&#xff0c; 也可以表示一组数字 [1, 2, 3, 4, 5] &#xff0c;从个人…

STL常用容器_2

目录 一、stcak容器&#xff08;栈容器&#xff09; 1、基本概念 2、常用接口 二、queue容器&#xff08;队列容器&#xff09; 1、基本概念 2、常用接口函数 三、list容器&#xff08;链表&#xff09; 1、基本概念 2、构造函数 3、赋值与交换 4、大小操作 5、插入…