564 字
3 分钟
前 K 个高频元素

题目描述#

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

解题思路#

  1. 频率统计:遍历数组,使用哈希表记录每个元素出现频率。
  2. 桶排序优化:创建长度为 n+1 的桶数组,以频率为下标存储对应元素。
  3. 逆序收集:从最高频率桶(最大下标)开始,收集元素直到获得 k 个结果。
  4. 提前终止:当结果集达到 k 个元素时立即返回。

关键洞察#

  1. 桶索引即频率:利用频率与数组索引的等价性,实现 O(1) 频率分组。
  2. 空间换时间:桶数组将排序复杂度从 O(n log n) 降至 O(n)。
  3. 频率边界明确:元素频率必在 [1, n] 范围内,避免无效桶空间。
  4. 同频元素批量处理:相同频率元素存储在同一桶中,简化收集逻辑。

复杂度分析#

指标说明
时间复杂度O(n):统计频率 O(n) + 构建桶 O(n) + 收集结果 O(n)
空间复杂度O(n):哈希表 O(n) + 桶数组 O(n)(最坏情况需存储所有元素)

代码实现#

/**
* 哈希 + 桶排序
* @link {https://leetcode.cn/problems/top-k-frequent-elements}
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var topKFrequent = function (nums, k) {
const cnt = new Map();
for (const x of nums) {
cnt.set(x, (cnt.get(x) ?? 0) + 1)
}
const maxCnt = Math.max(...cnt.values());
const buckets = Array.from({ length: maxCnt + 1 }, () => []);
for (const [x, c] of cnt.entries()) {
buckets[c].push(x);
}
const ans = [];
for (let i = maxCnt; i >= 0 && ans.length < k; i--) {
ans.push(...buckets[i])
}
return ans;
}

实际应用场景#

  1. 热门关键词提取:分析搜索日志中的高频词汇`
  2. 用户行为分析:电商平台购买频率最高的商品`
  3. 网络监控:检测高频访问IP地址`
  4. 推荐系统:根据点击频率推荐内容`

相似题目#

前 K 个高频元素
https://website-truelovings-projects.vercel.app/posts/algorithms/前-k-个高频元素/
作者
欢迎来到StarSky的网站!
发布于
2025-08-09
许可协议
CC BY-NC-SA 4.0