当前位置: 首页 > wzjs >正文

莆田建设企业网站毕节建设局网站

莆田建设企业网站,毕节建设局网站,宁波网站设计制作公司,现在什么网站做基础销量好文章目录 题目描述1. 使用堆(Priority Queue)解决TopK问题2. 利用排序实现知识复习:稳定排序和非稳定排序稳定排序(Stable Sort)非稳定排序(Unstable Sort) 1. 非稳定排序(快排&…

文章目录

    • 题目描述
    • 1. 使用堆(Priority Queue)解决TopK问题
    • 2. 利用排序实现
      • 知识复习:稳定排序和非稳定排序
        • 稳定排序(Stable Sort)
        • 非稳定排序(Unstable Sort)
      • 1. 非稳定排序(快排)
      • 2. 稳定排序
    • 4. 借助multimap反转键值对

题目描述

给定一个单词列表 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] 的数量]

在解决LeetCode 692题时,我们需要找到出现频率最高的前K个单词,并按频率降序排列。如果频率相同,则按字典序升序排列。本文将介绍多种解法,包括堆、排序(稳定/非稳定)、以及multimap反转键值对的方法,帮助读者深入理解问题并掌握相关技巧。

1. 使用堆(Priority Queue)解决TopK问题

  • 用map统计每个单词出现次数
  • 自己实现仿函数实现优先级规则,把所有pair(单词,频率)放入一个优先级队列
  • 回归topK问题,取出前k个数据

关键:仿函数Less

  1. 频率不同,出现频率低的优先级低
  2. 出现频率相同,则字典顺序大的优先级低

本题建大堆,less,实现less即可。先考虑value的比较(出现频率),若相同,比较key(string的字典顺序)

class Solution {
public://less这里是比较的优先级的大小struct myLess{//最好+const,因为可能这里是生成的临时对象,具有常性bool operator()(const pair<string,int>& kv1,const pair<string,int>& kv2) const{ //1.比较频率if(kv1.second < kv2.second){return true;}//2.比较字典顺序  字典序大于 看作 优先级小于if(kv1.second==kv2.second && kv1.first>kv2.first){return true;}return false;}};vector<string> topKFrequent(vector<string>& words, int k) {//先统计次数map<string,int> mp; for(const auto& str:words){mp[str]++;}//topK问题//因为要考虑 出现频率和字典顺序的两个优先级,因此自己实现一个仿函数//这里是priority_queue的构造函数弊端:容器适配器默认采用vector一般不需要更改,但是缺放在了第二个参数位置,所以自己实现仿函数的时候就需要把容器也写上;按理应该把仿函数放在第二个位置priority_queue<pair<string,int> , vector<pair<string,int>> ,myLess> maxHeap(mp.begin(),mp.end());vector<string> res;//取maxHeap中前k个数据的first放入 vectorwhile(k--){res.push_back(maxHeap.top().first);maxHeap.pop();}return res;}
};

2. 利用排序实现

知识复习:稳定排序和非稳定排序

稳定排序非稳定排序是排序算法中两个重要的概念,它们主要关注在排序过程中,相等元素的相对顺序是否保持不变。

稳定排序(Stable Sort)
  • 定义:如果排序算法能够保证相等元素在排序后的相对顺序与排序前的相对顺序一致,则该算法是稳定排序。
  • 举例:假设有一个序列 [A, B, C, D],其中 BC 的值相等(即 B = C)。如果排序后 B 仍然在 C 的前面(即 [A, B, C, D]),则该排序是稳定的。
  • 常见的稳定排序算法:
    • 冒泡排序(Bubble Sort)
    • 插入排序(Insertion Sort)
    • 归并排序(Merge Sort)
    • 计数排序(Counting Sort)
    • 基数排序(Radix Sort)
非稳定排序(Unstable Sort)
  • 定义:如果排序算法不能保证相等元素在排序后的相对顺序与排序前的相对顺序一致,则该算法是非稳定排序。
  • 举例:同样假设有一个序列 [A, B, C, D],其中 BC 的值相等(即 B = C)。如果排序后 C 可能在 B 的前面(即 [A, C, B, D]),则该排序是非稳定的。
  • 常见的非稳定排序算法:
    • 快速排序(Quick Sort)
    • 堆排序(Heap Sort)
    • 选择排序(Selection Sort)
    • 希尔排序(Shell Sort)

1. 非稳定排序(快排)

回到本题:

因为单词作为key构建的mapmap中序遍历本身是满足字典顺序的,排序如果只按照 pair(单词,频率)中的频率进行比较,那么频率相同的单词可能会改变相对顺序!因此需要自己控制仿函数

注意:排序的迭代器是 Random-access Iterator(随机访问迭代器),而map的迭代器是Bidirectional Iterator(双向迭代器), 所以要把map中的元素先导入到vector中

  • 利用map计数每一个单词出现次数
  • map中的元素pair放入vector
  • 对vector调用sort(快排)进行排序(降序)

降序排序 pair<单词,频率>,需要实现Greater

  1. 频率大的优先级高
  2. 频率相同,字典顺序小的优先级高
class Solution {
public://less这里是比较的优先级的大小struct myGreater{//最好+const,因为可能这里是生成的临时对象,具有常性bool operator()(const pair<string,int>& kv1,const pair<string,int>& kv2) const{ //1.比较频率if(kv1.second > kv2.second){return true;}//2.比较字典顺序  字典序小于 看作 优先级大于if(kv1.second==kv2.second && kv1.first < kv2.first){return true;}return false;}};vector<string> topKFrequent(vector<string>& words, int k) {//先统计次数map<string,int> mp; for(const auto& str:words){mp[str]++;}//数据放入vectorvector<pair<string,int>> sortV(mp.begin(),mp.end());//利用sort非稳定排序+控制仿函数(降序)sort(sortV.begin(),sortV.end(),myGreater());//排完序前k个放入结果vector<string> res;for(int i = 0;i<k;++i){res.push_back(sortV[i].first);}return res;}
};

2. 稳定排序

如上面的非稳定排序可以知道,如果利用的排序算法是稳定排序,那么仿函数就不需要强制考虑频率相同时,字典顺序的规则了,只需要考虑频率的大小来比较即可。因为本身序列就是借助map中序得到的,是字典有序的!

对于稳定排序,STL的<algorithm>头文件里是给出的stable_sort

class Solution {
public:struct myGreater{bool operator()(const pair<string,int>& kv1,const pair<string,int>& kv2) const{ //比较频率if(kv1.second > kv2.second){return true;}return false;}};vector<string> topKFrequent(vector<string>& words, int k) {//先统计次数map<string,int> mp; for(const auto& str:words){mp[str]++;}//数据放入vectorvector<pair<string,int>> sortV(mp.begin(),mp.end());//利用sort非稳定排序+控制仿函数(降序)stable_sort(sortV.begin(),sortV.end(),myGreater());//排完序前k个放入结果vector<string> res;for(int i = 0;i<k;++i){res.push_back(sortV[i].first);}return res;}
};

4. 借助multimap反转键值对

由于排序的思想影响,想到了 multimap也可以用来排序:

把出现频率作为key,允许多个出现次数相同的单词,降序即可得到前k个出现次数最大的!

补充知识:

STLmultimap中无论是升序(默认的 std::less)还是降序std::greater),当key相同时,新插入的元素都会放在已有相同key元素的右边

multimap<int,string>是按出现频率int,中序升序排列,key相同时,默认实现是插入到右边。中序时满足频率和字典顺序的要求

如:

遍历map:(apple 2),(love,2),并放入multimap

先插入(2,apple), 后插入(2,love),默认插入到(2,apple)的右边,因此中序的时候可以保证 出现频率key相同时,单词value依然按照字典顺序(得益于遍历map时已经是按照单词的升序排列了)

不过上面的情况是升序,multimap仿函数默认用less是按key升序排列。本题要求前k频率最高的单词,需要用greater降序排列(只需考虑频率,字典顺序已满足)

multimap默认使用key进行排序,而key又是int,因此直接使用库里面的即可greater<int>

注意

  1. 不能使用升序+反向迭代器遍历,因为倒着遍历时否则单词的字典顺序又无法保证了

  2. multimap 的仿函数(比较函数)只能作用于键(Key,而不能作用于整个 pair<Key, Value>。这是由 multimap 的设计决定的。其他类似priority_queue存在比较的容器,仿函数都是作用于所存放数据类型(T)。如果需求需要同时比较键和值,可以使用 vector + 自定义排序,或者手动处理相同键的情况

  • map<单词,频率> 统计单词出现次数
  • 把map中的key和value反转,放入multimap<频率,单词>
  • 通过控制multimap的仿函数Greater实现降序排列:频率大的优先级高
class Solution {
public:vector<string> topKFrequent(vector<string>& words, int k) {//先统计次数map<string,int> countMap; for(const auto& str:words){countMap[str]++;}//利用multimap,反转key和value的位置multimap<int,string,greater<int>> sortMap;for(const auto& kv : countMap){//频率作为key,单词作为valuesortMap.insert(make_pair(kv.second,kv.first));}vector<string> res;//取multimap前k个multimap<int,string,greater<int>>::iterator it = sortMap.begin();while(it!=sortMap.end() && k--){res.push_back(it->second);++it;}return res;}
};
http://www.dtcms.com/wzjs/549817.html

相关文章:

  • 网站建设的详细步骤如何挑选网站主机
  • 深圳微商城网站设计电话购物网站制作代码
  • 出售家教网站模板社群运营外包
  • 闸北专业做网站wordpress .less
  • 网站免费建站人生若只初相见04网站建设技术架构和语言
  • 网站改版升级总结免费网站添加站长统计
  • 网站后台密码忘记了营销推广公司案例
  • 天空彩票网站怎么做wordpress 自动 tag
  • 旅游网站建设背景如何在易语言上做网站
  • 网站开发网站开发东营网站建设tt0546
  • 大连网站优化怎么建立一个博客网站吗
  • 网站规划是什么意思做一家网站费用
  • 做网站80端口网站超市源码哪个好
  • 网站建设销售是什么163企业邮箱登陆
  • 网站建设专业知识免费一级域名网站
  • 网站建设安全服务协议正定seo
  • 保定网站制作方案东莞商城网站推广建设
  • 宁波企业网站seo电信备案网站打不开
  • 企业网站设计苏州手机网站菜单网页怎么做的
  • 最新的网站建设软件有哪些wordpress博客dux主题
  • 西安网站建设建站系统自己可以做网站
  • 自媒体网站建设要求wordpress自定义tag页面
  • 网站变exe文件怎么做江门seo
  • 廊坊市网站长春网站建设公司怎么样
  • 商务网站开发网站建设php文件html文件
  • 汕头公司网站建设去别人网站挂黑链
  • 网站转化率低北京备案网站负责人
  • 深圳大浪有做网站的吗网站开发最适合的浏览器
  • 手机网站建设代码广安建设厅官方网站
  • 黄浦网站建设公司郑州的做网站公司