
方法 1:用 vector
存储键值对,按频率排序(简单直接)
cpp
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
// 1. 统计每个元素的频率
unordered_map<int, int> freq;
for (int num : nums) {
freq[num]++;
}
// 2. 将键值对存入vector,便于按频率排序
vector<pair<int, int>> freq_vec(freq.begin(), freq.end());
// 3. 按频率降序排序(第二个元素是频率)
sort(freq_vec.begin(), freq_vec.end(),
[](const pair<int, int>& a, const pair<int, int>& b) {
return a.second > b.second; // 频率高的排在前
});
// 4. 取前k个元素的键
vector<int> result;
for (int i = 0; i < k; ++i) {
result.push_back(freq_vec[i].first);
}
return result;
}
};
进阶方法 2:用优先队列(堆)优化(时间复杂度 O (n log k))
cpp
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
// 1. 统计频率
unordered_map<int, int> freq;
for (int num : nums) {
freq[num]++;
}
// 2. 用小顶堆存储前k个高频元素(堆顶是最小的高频元素)
// 堆中元素是 (频率, 元素),按频率升序排列
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
for (auto& pair : freq) {
pq.push({pair.second, pair.first});
// 当堆大小超过k,弹出最小的高频元素
if (pq.size() > k) {
pq.pop();
}
}
// 3. 从堆中取出结果(此时堆中是前k个高频元素)
vector<int> result;
while (!pq.empty()) {
result.push_back(pq.top().second);
pq.pop();
}
// 由于堆是小顶堆,结果是从小到大的,如需保持高频在前可反转
reverse(result.begin(), result.end());
return result;
}
};
用小顶堆只保留前 k 个高频元素,每次插入后若超过 k 就弹出最小的,效率更高,尤其当 n
很大而 k
较小时。