统计频次后排序取前 k,或用大小为 k 的最小堆保留频次最高的 k 个。
OJ: leetcodecn
题目 ID: top-k-frequent-elements
难度:普及+/提高
标签:堆排序哈希表
日期: 2026-07-29 12:18
题意
返回数组中频次前 k 高的元素。
思路
先用哈希表统计每个元素的频次,再按频次降序排序取前 k 个。C++ 直接排序;Python 用 Counter.most_common(k)。
代码
cpp
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<int> topKFrequent(vector<int> &nums, int k) {
unordered_map<int, int> cnt;
for (int x : nums)
cnt[x]++;
vector<pair<int, int>> v(cnt.begin(), cnt.end());
sort(v.begin(), v.end(), [](auto &a, auto &b) { return a.second > b.second; });
vector<int> ans(k);
for (int i = 0; i < k; i++)
ans[i] = v[i].first;
return ans;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, k;
cin >> n >> k;
vector<int> a(n);
for (int &x : a)
cin >> x;
for (int x : Solution().topKFrequent(a, k))
cout << x << ' ';
return 0;
}python
#!/usr/bin/env python3
from typing import List
from collections import Counter
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
return [x for x, _ in Counter(nums).most_common(k)]
def main():
n, k = map(int, input().split())
a = list(map(int, input().split()))
print(*Solution().topKFrequent(a, k))
if __name__ == "__main__":
main()复杂度
- 时间复杂度:
(排序),可用堆优化到 。 - 空间复杂度:
,频次表。
总结
频次统计 + 排序取前 k 是本题最直接的解法。堆优化时维护大小为 k 的最小堆,按频次弹出不够格的元素。