leetcode 347. 前 K 个高频元素 medium
题目描述:
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
说明:
你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
解题思路:
用哈希表统计各元素的频率,然后用最小堆保存前k个高频元素(或者用快速选择算法/ 桶排也行)
代码:
//
//小顶堆
bool cmp(const pair<int,int> &a, const pair<int,int> &b){
return a.second>b.second;
}
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
// 元素值-》次数
unordered_map<int,int> hash;
for(int i:nums)
hash[i]++;
priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(cmp) *> pq(cmp);
for(auto i:hash){
if(pq.size()<k) pq.push(i);
else if(i.second>pq.top().second){
pq.pop();
pq.push(i);
}
}
vector<int> res;
while(pq.size()){
res.push_back(pq.top().first);
pq.pop();
}
return res;
}
};
// 桶排
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
// 统计每个number出现的次数,保留最大次数 建桶
unordered_map<int, int> hash;
int max_cnt = INT_MIN;
for (auto i:nums){
hash[i]++;
max_cnt = max(max_cnt, hash[i]);
}
vector<vector<int>> buckets(max_cnt+1);
for (auto &i: hash){
buckets[i.second].push_back(i.first);
}
vector<int> res;
for (int i = buckets.size()-1; i >= 0; i--){
if (res.size() == k)
break;
for (int j = 0; j < buckets[i].size() && res.size() < k; j++)
res.push_back(buckets[i][j]);
}
return res;
}
};