class Solution {
public:
//nlog(k)使用哈希表统计每个数字出现的个数,然后维护一个大小为k的小顶堆即可。
vector<int> topKFrequent(vector<int>& nums, int k) {
priority_queue<pair<int,int>, vector<pair<int, int>>, greater<pair<int,int>>> q;
unordered_map<int, int> hash;
for(int x :nums) hash[x]++; //每个num和其出现次数
int i = 0;
for(auto &it:hash){
if(i < k) {
i++;
q.push(make_pair(it.second, it.first));
} else {
if(q.top().first < it.second) {
q.pop();
q.push(make_pair(it.second, it.first));
}
}
}
vector<int> res(k);
for(int i=0; i<k; i++){
res[i] = q.top().second;
q.pop();
}
return res;
}
};
class Solution {
public:
//O(n)首先用哈希表统计出所有数出现的次数。由于所有数出现的次数都在 1 到 n之间,所以我们可以用计数排序的思想,
//统计出次数最多的前 k 个元素的下界。然后将所有出现次数大于等于下界的数输出。
vector<int> topKFrequent(vector<int>& nums, int k) {
int n = nums.size();
unordered_map<int, int> hash;
for(auto x : nums) hash[x]++; //每个字出现多少次
vector<int> s(n+1,0); //每个次数,有多少个字
for(auto &x : hash) s[x.second]++;
int t = 0, i = n; //i为出现次数的下界
while(t < k) {
t += s[i];
i--;
}
vector<int> res;
for(auto &x : hash)
if(x.second > i) res.push_back(x.first);
return res;
}
};