LeetCode 347
https://leetcode.cn/problems/top-k-frequent-elements/description/
难度:中等
高频面试题汇总:https://www.yuweihung.com/posts/2025/lc-hot/
桶排序。
第一步
答案与元素的出现次数有关,我们首先用一个哈希表 cnt 统计每个元素的出现次数。哈希表的 key 是元素值,value 是 key 在数组中的出现次数。
第二步
设出现次数最大值为 maxCnt,由于 maxCnt≤n,我们可以用桶排序,把出现次数相同的元素,放到同一个桶中。
创建一个大小为 maxCnt+1 的列表 buckets,其中 buckets[c] 存储出现次数为 c 的元素。(每个 buckets[c] 都是一个列表)
遍历 cnt,把出现次数为 c 的元素 x 添加到 buckets[c] 中。
第三步
倒序遍历 buckets,把 buckets[c] 中的元素加到答案中。
一旦答案的长度等于 k,就立刻返回答案。
时间复杂度:O(n),其中 n 是 nums 的长度。
空间复杂度:O(n)。
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
// 第一步:统计每个元素的出现次数
unordered_map<int, int> cnt;
int max_cnt = 0;
for (int x : nums) {
cnt[x]++;
max_cnt = max(max_cnt, cnt[x]);
}
// 第二步:把出现次数相同的元素,放到同一个桶中
vector<vector<int>> buckets(max_cnt + 1);
for (auto& [x, c] : cnt) {
buckets[c].push_back(x);
}
// 第三步:倒序遍历 buckets,把出现次数前 k 大的元素加入答案
vector<int> ans;
// 注意题目保证答案唯一,一定会出现某次 insert 后 ans.size() 恰好等于 k 的情况
for (int i = max_cnt; i >= 0 && ans.size() < k; i--) {
ans.insert(ans.end(), buckets[i].begin(), buckets[i].end());
}
return ans;
}
};