第一步
答案和元素的出现次数有关,我们首先用一个哈希表 cnt 统计每个元素的出现次数。哈希表的 key 是元素值,value 是 key 在数组中的出现次数。
此时问题变成:
返回一个列表,包含前 k 大的出现次数对应的元素值。
第二步
设出现次数最大值为 maxCnt,由于 maxCnt≤n,我们可以用桶排序,把出现次数相同的元素,放到同一个桶中。
创建一个大小为 maxCnt+1 的列表 buckets,其中 buckets[c] 存储出现次数为 c 的元素。(每个 buckets[c] 都是一个列表)
遍历 cnt,把出现次数为 c 的元素 x 添加到 buckets[c] 中。
第三步
倒序遍历 buckets,把 buckets[c] 中的元素加到答案中。
一旦答案的长度等于 k,就立刻返回答案。
注 1:题目保证答案唯一,所以一定会出现答案长度恰好等于 k 的情况。
注 2:可以按任意顺序返回答案。比如示例 1 返回 [1,2] 还是 [2,1] 都是正确的。
Python3
Java
Java 数组
C++
Go
JavaScript
Rust
class Solution {
public int[] topKFrequent(int[] nums, int k) {
// 第一步:统计每个元素的出现次数
Map<Integer, Integer> cnt = new HashMap<>();
for (int x : nums) {
cnt.merge(x, 1, Integer::sum); // cnt[x]++
}
int maxCnt = Collections.max(cnt.values());
// 第二步:把出现次数相同的元素,放到同一个桶中
List<Integer>[] buckets = new ArrayList[maxCnt + 1];
Arrays.setAll(buckets, i -> new ArrayList<>());
for (Map.Entry<Integer, Integer> e : cnt.entrySet()) {
buckets[e.getValue()].add(e.getKey());
}
// 第三步:倒序遍历 buckets,把出现次数前 k 大的元素加入答案
int[] ans = new int[k];
int j = 0;
for (int i = maxCnt; i >= 0 && j < k; i--) {
for (int x : buckets[i]) {
ans[j++] = x;
}
}
return ans;
}
}
复杂度分析
时间复杂度:O(n),其中 n 是 nums 的长度。
空间复杂度:O(n)。
分类题单
如何科学刷题?
滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
二分算法(二分答案/最小化最大值/最大化最小值/第K小)
单调栈(基础/矩形面积/贡献法/最小字典序)
网格图(DFS/BFS/综合应用)
位运算(基础/性质/拆位/试填/恒等式/思维)
图论算法(DFS/BFS/拓扑排序/最短路/最小生成树/二分图/基环树/欧拉路径)
动态规划(入门/背包/状态机/划分/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
链表、二叉树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA/一般树)
字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)
我的题解精选(已分类)
欢迎关注 B站@灵茶山艾府
上一篇题解
347. 前 K 个高频元素
下一篇题解
【C++】小白友好【优先队列的基础知识】
评论 (8)
排序:最热
评论
Seabiscuit
来自 江苏
2025.04.18
第一!!!!!前几天我就说这个经典题目为啥没有灵神的解析,今天突然看到了,必须狠狠学习一波!
1
回复
TommyZjl
来自 江苏
2025.05.06
真无敌
0
回复
分享
我是无敌的呀
来自 上海
2025.04.24
我直接:
cnt = Counter(nums)
ans = cnt.most_common(k)
作者:灵茶山艾府
链接:https://leetcode.cn/problems/top-k-frequent-elements/solutions/3655287/tong-pai-xu-on-xian-xing-zuo-fa-pythonja-oqq2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。