347 Top K Frequent Elements

本文介绍了一种用于找出数组中出现频率最高的K个数的算法。该算法首先通过遍历数组来构建一个字典,字典的键为数组中的数,值为对应的出现次数。接着,对字典进行降序排序,并选取前K个数作为结果返回。
题目:给定一个数组,输出频度最高的K个数。
解题思路:建立一个字典<数,数的频度>,将字典按value的降序排序,然后输出前K个数。
重点:Dictionary的降序排序(一般来说,对字典排序使没有意义的)


public class Solution {
    public IList<int> TopKFrequent(int[] nums, int k) {
         Dictionary<int, int> numFrequency = new Dictionary<int, int>();
            for (int i = 0; i < nums.Length; i++)
            {
                if (numFrequency.ContainsKey(nums[i]))
                    numFrequency[nums[i]]++;
                else
                {
                    numFrequency.Add(nums[i], 1);
                }
            }
            var results = numFrequency.OrderByDescending(o => o.Value).ToDictionary(o=>o.Key,v=>v.Value);
            List<int> kNums = new List<int>();
            int j = 0;
            foreach(int key in results.Keys)
            {
                j++;
                if (j <= k)
                    kNums.Add(key);
            }
            return kNums;
        
    }
}
### C++ 实现 Top-K 算法 Top-K 问题是常见的算法问题之一,通常用于从大量数据中找到排名靠前的 K 个元素。下面是一个完整的 C++ 示例代码及其解释。 #### 示例代码 ```cpp #include <iostream> #include <vector> #include <queue> #include <functional> using namespace std; // 定义比较函数,使得 priority_queue 成为最小堆 struct Compare { bool operator()(const pair<int, int>& a, const pair<int, int>& b) { return a.second < b.second; // 按照频率从小到大排序 } }; vector<int> topKFrequentElements(vector<int>& nums, int k) { unordered_map<int, int> frequencyMap; // 记录每个元素出现的次数 for (auto num : nums) { frequencyMap[num]++; } // 使用优先队列(最小堆)存储频率最高的 k 个元素 priority_queue<pair<int, int>, vector<pair<int, int>>, Compare> minHeap; for (auto& entry : frequencyMap) { minHeap.push({entry.first, entry.second}); if (minHeap.size() > k) { minHeap.pop(); // 移除堆顶元素(频率最低) } } vector<int> result; while (!minHeap.empty()) { result.push_back(minHeap.top().first); // 提取堆中的元素 minHeap.pop(); } reverse(result.begin(), result.end()); // 结果按频率降序排列 return result; } int main() { vector<int> nums = {1, 1, 1, 2, 2, 3}; int k = 2; vector<int> result = topKFrequentElements(nums, k); cout << "Top-" << k << " frequent elements: "; for (auto elem : result) { cout << elem << " "; } cout << endl; return 0; } ``` --- ### 代码详解 1. **输入准备** - 输入数组 `nums` 是待处理的数据集。 - 参数 `k` 表示需要找出的最高频次的元素数量。 2. **构建频率表** - 使用 `unordered_map<int, int>` 存储每个元素的出现次数[^1]。 - 遍历整个数组,统计每个元素的频率。 3. **使用最小堆筛选 Top-K 元素** - 创建一个自定义比较规则的小根堆(`priority_queue`),其中堆顶是最不频繁的元素。 - 遍历频率表,将元素插入堆中。如果堆的大小超过了 `k`,则弹出堆顶元素(即频率最低的元素)。 4. **提取结果** - 堆中剩余的元素就是频率最高的 `k` 个元素。 - 将这些元素依次取出并存入结果向量中。 5. **输出结果** - 输出最终的 Top-K 频繁元素列表。 --- ### 性能分析 - **时间复杂度**: - 统计频率阶段:\( O(n) \),其中 \( n \) 是数组长度。 - 构建堆阶段:每次插入或删除操作的时间复杂度为 \( O(\log{k}) \),总共最多进行 \( m \) 次(m 为不同元素的数量)。因此这一部分的时间复杂度为 \( O(m \cdot \log{k}) \)[^1]。 - 整体时间复杂度为 \( O(n + m \cdot \log{k}) \)。 - **空间复杂度**: - 主要由频率表和堆占用的空间决定,分别为 \( O(m) \) 和 \( O(k) \)。整体空间复杂度为 \( O(m + k) \)。 --- ### 示例运行 假设输入数组为 `{1, 1, 1, 2, 2, 3}`,参数 `k=2`: - 频率表为:`{1 -> 3, 2 -> 2, 3 -> 1}` - 最小堆逐步变化过程: - 插入 `(1, 3)` → 堆为 `[(1, 3)]` - 插入 `(2, 2)` → 堆为 `[(2, 2), (1, 3)]` - 插入 `(3, 1)` 并移除堆顶 `(3, 1)` → 堆为 `[(2, 2), (1, 3)]` - 最终结果为 `[1, 2]`。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值