给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
- 示例 1:
输入: ["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 次。
- 注意:
假定 k 总为有效值, 1 ≤ k ≤ 集合元素数。
输入的单词均由小写字母组成。
- 扩展练习:
尝试以 O(n log k) 时间复杂度和 O(n) 空间复杂度解决。
构建小顶堆,然后从小顶堆中读出结果到数组中,最后将数组内容重置。
class Solution {
public:vector<string> topKFrequent(vector<string>& words, int k) {// 统计单词频率unordered_map<string, int> m;for (const auto& x: words) {m[x]++;}auto cmp = [](const pair<int, string>& lhs, const pair<int, string>& rhs){if (lhs.first != rhs.first) {return lhs.first > rhs.first;} else {return lhs.second < rhs.second;}};priority_queue<pair<int, string>, vector<pair<int, string>>, decltype(cmp)> my_pri(cmp);auto iter = m.begin();for (int i=0; i<k; i++) {my_pri.push(make_pair(iter->second, iter->first));iter++;}for(; iter != m.end(); iter++) {my_pri.push(make_pair(iter->second, iter->first));my_pri.pop();}vector<string> res;while(k > 0) {res.push_back(my_pri.top().second);my_pri.pop();k--;}reverse(res.begin(), res.end());return res;}
};// class Solution {
// public:
// struct cmp{
// bool operator ()(pair<int,string> &a,const pair<int,string> &b){
// if(a.first!=b.first){
// return a.first<b.first;
// }
// else return a.second>b.second;
// }
// };
// vector<string> topKFrequent(vector<string>& words, int k) {
// unordered_map<string,int> mp;
// for(auto s:words) mp[s]++;
// priority_queue<pair<int,string>,vector<pair<int,string>>,cmp> pq;
// for(auto m:mp){
// pq.push(make_pair(m.second,m.first));
// }
// vector<string> res;
// while(k){
// res.push_back(pq.top().second);
// pq.pop();
// k--;
// }
// return res;// }
// };