LeetCode692.前K个高频单词原题链接:前K个高频单词
1. 需要了解的知识点
数据结构
unordered_map: 哈希函数组成的 无序 map。(此题unordered_map无序比有序map效率更高)
multimap: 可重复的map
相关函数API
vector<int>
empty(): 判断Vector是否为空
size(): 返回Vector元素数量的大小
rbegin(),rend(): 反向迭代器
clear(): 清空所有元素
sort(): #include<algorithm>
头文件下,链表排序,默认是升序
multimap<int, string>
emplace():向容器中添加“新键值对”的效率,要比 insert() 方法高。
2. 难点:
相同出现频率,按字母顺序排序
3. 思路
1.计算频率,将元素放入unordered_map中
2.频率排序,将unordered_map的first,second倒置放入multimap中
3.遍历multimap元素,碰到频率相同的就放入一个临时数组中进行字母顺序排序,当频率不同时,就把数组中的元素放到需要返回的数组中
<==就是利用数据结构倒来倒去==>
变量定义的解释
vector<string> vec: 需要返回的数组
unordered_map<string, int> maps:
maps.first为words里的单个单词(string)-----> maps.second为单个string的频率(int)
multimap<int, string> res_topmap:
res_topmap.first为单个string的频率(int)-----> res_topmap.second 为words里的单个单词(string)
vector<string> sort_vec; 临时的用于按字母顺序排序相同频率的数组
4. 代码注释
class Solution {
public:
vector<string> topKFrequent(vector<string>& words, int k) {
vector<string> vec; /*需要返回的数组*/
if (words.empty()) /*words为空返回空数组*/
return vec;
unordered_map<string, int> maps; /*用于统计每个单词的频率*/
multimap<int, string> res_topmap; /*按单词频率排序*/
for (auto i : words)
maps[i]++; /*将单词放入unordered_map*/
for (auto item = maps.begin(); item != maps.end(); item++)
{
res_topmap.emplace(item->second, item->first); /*maps的first为res_topmap的second,maps的second为res_topmap的first,将键值对放入可重复map中。 */
}
/*注意此时res_ropmap的排序频率从小到大,而字母的顺序为从大到小(下面调整字母顺序)*/
vector<string> sort_vec; /*定义一个相同频率字母顺序排序*/
int last = res_topmap.rbegin()->first; /*记录上一个元素的频率*/
for (auto item = res_topmap.rbegin(); item != res_topmap.rend(); item++) /*反向遍历,反向频率从大到小*/
{
if (item != res_topmap.rbegin() && item->first != last) /*如果当前元素频率和前一个频率不相等,并且不是第一个元素(第一个元素没有前一个元素)*/
{
sort(sort_vec.begin(), sort_vec.end()); /*字符串按字母顺序从小到大排序*/
for (auto i : sort_vec) /*遍历sort_vec,将里面元素按顺序压入需要返回的vec中*/
{
vec.push_back(i);
if (vec.size() >= k) /*题目只需要返回k个单词*/
return vec;
}
sort_vec.clear(); /*清空vector<string>*/
}
sort_vec.push_back(item->second); /*相同频率的就压入sort_vec中*/
last = item->first; /*移动到下一个元素之前保存到last中*/
}
if (!sort_vec.empty()) /*考虑到后面的元素频率相同,sort_vec中还有元素没有压入返回的vec中*/
{
sort(sort_vec.begin(), sort_vec.end()); /*同上*/
for (auto i : sort_vec)
{
if (vec.size() >= k)
return vec;
vec.push_back(i);
}
}
return vec;
}
};
不太喜欢压行
4. 总结反思
vector<string> topKFrequent(vector<string>& words, int k) {
vector<string> vec;
map<string, int> maps;
multimap<std::pair<int, string>, string> res_topmap;
for (auto i : words)
maps[i]++;
for (auto item = maps.begin(); item != maps.end(); item++)
{
string str;
for (auto k : item->first)
{
str.push_back('z'-k+'a');
}
res_topmap.emplace(std::pair<int,string>(item->second,str), item->first);
}
for (auto item = res_topmap.rbegin(); item != res_topmap.rend() && k > 0; item++)
{
vec.push_back(item->second);
k--;
}
return vec;
}
一开始用这样的类型结构处理省事,但测试到104这个点有点麻烦,默认的字母顺序是相反的并且难以改动,干脆代码重构了。
![alt 测试图片 alt 测试图片](https://i-blog.csdnimg.cn/blog_migrate/22411211d4cb8db20b3dacf455f2a7bb.png)