class Solution {
public:
vector<string> topKFrequent(vector<string>& words, int k) {
unordered_map<string, int> cnt;
for (auto& word : words) {
cnt[word]++;
}
//ture-->满足升序(a<=b),false不满足升序(a>b)
auto cmp = [](const pair<string, int>& a, const pair<string, int>& b) -> bool {
return a.second == b.second ? a.first < b.first : a.second > b.second;
};//a.second>b.second为true则a<b,则b在顶端,所以这个比较函数使second小的在顶端
priority_queue<pair<string, int>, vector<pair<string, int>>, decltype(cmp)> que(cmp);
//在定义优先队列时,我们需要显式指定比较函数的类型,而Lambda表达式是一个匿名函数对象,
//它的类型是不具名的,所以此处不可用lambda表达式,且需要用decltype获取cmp对象的类型
for (auto& it : cnt) {
que.emplace(it);
if (que.size() > k) {
que.pop();
}
}
vector<string> ret(k);
for (int i = k - 1; i >= 0; i--) {
ret[i] = que.top().first;
que.pop();
}
return ret;
}
};
注意
- auto cmp = [] .......;这里定义了一个函数对象,用于后续传递给优先队列
priority_queue<pair<string, int>, vector<pair<string, int>>, decltype(cmp)> que(cmp);
- 以上构建优先队列的代码中,有三个参数,以下对其分别解释:
(1)pair<string, int>
这是优先队列中存储的元素类型,和哈希表cnt中的类型相同
(2)vector<pair<string, int>>
这里指定优先队列底层所使用的容器类型,为vector
(3)decltype(cmp)
这里指定优先队列所使用的比较函数类型,使用了decltype自动获取元素类型
(4)que(cmp)将cmp对象传递给优先队列
- 注意优先队列以及sort函数中所自定义的比较函数,如何对排序、优先队列造成影响
以此处cmp
函数为例,其传入a,b两个对象,使用return a.second == b.second ? a.first < b.first : a.second > b.second;
返回结果。
(1)比较函数的大前提是:返回ture代表a"<="b,返回false代表a">"b,这里的大小关系表示了a,b元素在优先队列or排序中的顺序,例如a"<="b时,排序则a在前,b在后;优先队列则b优先,在堆顶;(因为排序默认升序,优先队列默认使用大根堆)
(2)所以此处a.second>b.second为true时候则a"<="b,则b在堆顶,所以这个比较函数使得second小的在顶端