前k个高频词

https://leetcode.cn/problems/top-k-frequent-words/

给定一个单词列表 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 次。

注意:

1 <= words.length <= 500

1 <= words[i] <= 10

words[i] 由小写英文字母组成。

k 的取值范围是 [1, 不同 words[i] 的数量]

思路

解题思路

​ 本题和前k个高频元素的小顶堆实现有点像,可以参考着做。首先我们需要先统计words中每个元素出现的次数,建立一个hashmap

很自然的,我们希望对这个hashmap进行排序,最好是按值排序,这样问题就解决了。

​ 但是,unordered_map本身是无序的,不支持排序。因此在统计完对应元素出现的次数之后,我们还需要将键值对取出,放入另外的支持排序的数据结构中进行排序处理

​ 并且,由于题目的要求,我们需要自定义排序规则(编写仿函数cmp)。可以选择vector作为排序的容器载体,使用值按从大到小完成排序之后,返回k个pair的first(键)即可

排序仿函数编写

​ 注意,这里我们在编写cmp时要满足两个规则:vector中元素按值从大到小降序排序、如果值相等则按照键的字典序大小进行排序

​ 在 bool operator() 函数中,它根据给定的规则比较了两个 pair<string, int> 类型的对象 p1 和 p2。其中,p1.second 表示字符串 p1 出现的次数,p1.first 表示字符串本身。函数返回值为 true 表示 p1 在排序中应该出现在 p2 的前面,而返回值为 false 则表示 p1 应该出现在 p2 的后面。

​ 这里不能直接使用 return p1.second > p2.second; 是因为如果有多个字符串的出现次数相同,则需要按字典序升序排列字符串,即在出现次数相同的情况下,需要同时比较字符串的大小。因此,我们需要在重载函数中加入额外的比较操作来满足题目的要求。

​ 具体来说,重载函数首先比较两个 pair<string, int> 中的出现次数,如果出现次数不同,则将出现次数多的字符串排在前面;如果出现次数相同,则比较两个字符串的字典序,将字典序小的字符串排在前面。综合这两种比较规则,就能够得到题目所要求的排序结果。

什么是字典序?

字典序(Lexicographic Order)是一种字符串之间的大小比较方式,也可以称为字母表顺序、字母表序或词典序。在字典序中,字符串的大小关系取决于它们每个位置上的字符的 ASCII 码值的大小关系。具体来说,给定两个字符串 s 和 t,如果从左到右逐位比较它们对应位置上的字符,遇到不同的字符时,则以这两个字符的 ASCII 码值的大小关系来确定它们之间的大小关系,如下所示:

  1. 如果 s[i] < t[i],则 s 小于 t;
  2. 如果 s[i] > t[i],则 s 大于 t;
  3. 如果 s[i] = t[i],则继续比较下一个字符,直到找到一个不同的字符或者比较完整个字符串。

举例来说,"abc" 小于 "acd",因为在第 2 个位置处 'b' 的 ASCII 码值小于 'c' 的 ASCII 码值。类似地,"apple" 小于 "application",因为前者长度较短,而在前 5 个字符处与后者相同,因此按照字典序规则,前者排在后者前面。

在实际编程中,我们通常会用到 operator< 操作符来实现字符串之间的字典序比较。例如,对于两个字符串 s 和 t,可以使用 s < t 来判断它们的大小关系。

代码

// 定义一个Solution类
class Solution {
public:
// 定义一个嵌套类cmp用于排序
class cmp{
public:
// 重载()运算符,用于比较两个pair<string, int>类型的对象
bool operator()(pair<string, int>& p1, pair<string, int>& p2){
// 按pair值比较,如果p1.second大于p2.second,则返回true,否则返回false
if(p1.second != p2.second) return p1.second > p2.second;
// 按pair键比较,如果p1.second等于p2.second(出现次数相等),则按字典序比较p1.first和p2.first,如果p1.first小于p2.first,则返回true,否则返回false
else return p1.first < p2.first;
}
};
vector<string> topKFrequent(vector<string>& words, int k) {
unordered_map<string, int> hashmap;// 定义一个unordered_map,用于统计每个字符串在words中出现的次数
for(int i = 0; i < words.size(); ++i) hashmap[words[i]]++; // 将哈希表中的键值对转换成pair<string, int>类型的vector,以便排序
vector<pair<string, int>> vec4sort(hashmap.begin(), hashmap.end());
// 使用自定义的cmp类进行排序,按照字符串出现的次数进行降序排序,如果次数相同则按字典序升序排序
sort(vec4sort.begin(), vec4sort.end(), cmp()); vector<string> res;// 定义一个空的vector<string>,用于存储结果
// 将排序后的前k个pair<string, int>中的string添加到res中
for(int i = 0; i < k; ++i){
res.push_back(vec4sort[i].first);
}
return res;// 返回结果向量
}
};

【LeetCode哈希表】前k个高频词,利用哈希表+vector进行排序操作的更多相关文章

  1. [LeetCode] Top K Frequent Words 前K个高频词

    Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ...

  2. 【LeetCode题解】347_前K个高频元素(Top-K-Frequent-Elements)

    目录 描述 解法一:排序算法(不满足时间复杂度要求) Java 实现 Python 实现 复杂度分析 解法二:最小堆 思路 Java 实现 Python 实现 复杂度分析 解法三:桶排序(bucket ...

  3. [LeetCode] Top K Frequent Elements 前K个高频元素

    Given a non-empty array of integers, return the k most frequent elements. For example,Given [1,1,1,2 ...

  4. LeetCode:前K个高频单词【692】

    LeetCode:前K个高频单词[692] 题目描述 给一非空的单词列表,返回前 k 个出现次数最多的单词. 返回的答案应该按单词出现频率由高到低排序.如果不同的单词有相同出现频率,按字母顺序排序. ...

  5. LeetCode:前K个高频元素【347】

    LeetCode:前K个高频元素[347] 题目描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [ ...

  6. [LeetCode] 347. Top K Frequent Elements 前K个高频元素

    Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [ ...

  7. Java实现 LeetCode 692 前K个高频单词(map的应用)

    692. 前K个高频单词 给一非空的单词列表,返回前 k 个出现次数最多的单词. 返回的答案应该按单词出现频率由高到低排序.如果不同的单词有相同出现频率,按字母顺序排序. 示例 1: 输入: [&qu ...

  8. 代码随想录算法训练营day12 | leetcode 239. 滑动窗口最大值 347.前 K 个高频元素

    基础知识 ArrayDeque deque = new ArrayDeque(); /* offerFirst(E e) 在数组前面添加元素,并返回是否添加成功 offerLast(E e) 在数组后 ...

  9. Java实现 LeetCode 347 前 K 个高频元素

    347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输 ...

  10. 前 K 个高频元素问题

    前 K 个高频元素问题 作者:Grey 原文地址: 前 K 个高频元素问题 题目描述 LeetCode 347. Top K Frequent Elements 思路 第一步,针对数组元素封装一个数据 ...

随机推荐

  1. [转帖]兆芯官方的CPU测试成绩,我复现不了

      https://baijiahao.baidu.com/s?id=1734998483605483848 下图是兆芯网官上的公开测试成绩,测试对象是3.0GHz的KX-U6880A. 有几个问题: ...

  2. Linux用户以及ssh安全相关设置

    Linux用户相关操作 摘要 最近重保, 需要进行网络安全防护. 部分同事处理过程总是顺序有一些不太对的情况. 同时发现自对Linux用户设置也存在很多不清不楚的地方 所以趁着周末学习和总结一下. 用 ...

  3. VM PowerCli的简单安装和使用学习

    1. Win10 上面安装 下载 zip包并且进行安装 win10 已经带了powershell 安装比较简单, 只不过安装时会提示 powershell的权限有问题需要打开powershell 执行 ...

  4. Redis labs 的安装

    Install and setup This guide shows how to install Redis Enterprise Software, which includes several ...

  5. Rsync的简单使用

    Rsync的简单使用 需求 一个运行很久的系统里面可能包含了非常多的垃圾文件. 但是又不可能随便删除, 很多垃圾可能有某些奇葩的用法. 有时候新建一个应用复制文件的话比较浪费磁盘和带宽. 所以这里简单 ...

  6. canvas操作图片像素点保证你看的明明白白

    开场白 今天遇到一个场景:就是更改一个图片的颜色: 当听到这个.我直呼好家伙:这个是要上天了呀. 但是仔细一思考:借助canvas好像也能实现: 于是下来研究了一下,并不难: 我们下面来看看怎么实现的 ...

  7. 【主流技术】15 分钟掌握 Redis 的安装部署和基本特性

    目录 前言 一.Redis 概述 1.1Redis 是什么? 1.2Redis 能做什么? 1.3基础知识 二.Redis 安装与基本命令 2.1Windows 安装 方式一 方式二 2.2Linux ...

  8. C/C++ 使用CRC检测内存映像完整性

    前面的那一篇文章中所使用的技术只能有效抵抗解密者直接修改硬盘文件,当我们使用动态补丁的时候,那么内存中同样不存在校验效果,也就无法抵御对方动态修改机器码了,为了防止解密者直接对内存打补丁,我们需要在硬 ...

  9. C# 通过VMI接口获取硬件ID

    使用C#语言实现通过VMI(虚拟机监控器)接口来获取硬件ID的过程.VMI是一种用于虚拟化环境的接口,用于管理虚拟机和宿主机之间的通信和资源共享.具体实现中,需要通过添加System.Manageme ...

  10. Pdfium.Net.Free 一个免费的Pdfium的 .net包装器--创建字符子集

    项目地址: Pdfium.Net:https://github.com/1000374/Pdfium.Net PdfiumViewer:https://github.com/1000374/Pdfiu ...