692. 前K个高频单词
思路:
求前k大的,并且要记录出现的次数,那么就想到是堆+hash表了。
然后就是hash表记录次数的同时加进堆里,但是这里就出现一个问题,当出现的次数一样的时候没法按字母大小排序。所以我们得自己写堆的排序函数:
看了官方题解,使用的lambda函数。
方法如下
auto cmp = [](const pair<string,int>& a, const pair<string,int>&b){
return a.second == b.second ? a.first < b.first : a.second > b.second;
};
priority_queue<pair<string,int>,vector<pair<string,int> >,decltype(cmp) > pq(cmp);
这里的decltype()函数能从表达式类型推断出要定义的变量类型,又因为lambda是匿名函数,所以decltype获取了匿名函数的类型,lambda返回的是匿名对象,那么在我们将lambda函数实例化的时候要作为参数传入pq里。
这里用pair是因为unordered_map底层是每个元素是pair构造的,如果是unordered_map<string,int>,那么里面每个元素都为pair<string,int>。
代码如下:
class Solution {
public:
vector<string> topKFrequent(vector<string>& words, int k) {
unordered_map<string,int> cnt;
for(auto& word:words){
cnt[word]++;
}
auto cmp = [](const pair<string,int>& a, const pair<string,int>&b){
return a.second == b.second ? a.first < b.first : a.second > b.second; //如果次数相等就比较字母顺序,否则就比较出现频率的大小
};
priority_queue<pair<string,int>,vector<pair<string,int> >,decltype(cmp) > pq(cmp);
for(auto& it : cnt){
pq.emplace(it);
if(pq.size()>k) pq.pop();
}
vector<string> res(k);
for(int i=k-1;i>=0;--i){
res[i]=pq.top().first;
pq.pop();
}
return res;
}
};