diff --git a/problems/0347.前K个高频元素.md b/problems/0347.前K个高频元素.md index 3d6c95d2..9f5e9f31 100644 --- a/problems/0347.前K个高频元素.md +++ b/problems/0347.前K个高频元素.md @@ -2,35 +2,48 @@ ## 思路 +这道题目主要涉及到如下三块内容: +1.要统计元素出现频率 +2.对频率排序 +3.找出前K个高频元素 + +首先统计元素出现的频率,这一类的问题可以使用map来进行统计。 + +然后是对频率进行排序,这里我们可以使用一种 容器适配器就是优先级队列。 为什么不用快排呢, 使用快排我们要向map转换为vector的结构,然后对整个数组进行排序, 而这种场景下,我们其实只需要维护k个有序的序列就可以了,所以使用优先级队列是最优的。 + +最后我们从优先级队列里找出前k个元素,就可以了。 ## C++代码 ``` class Solution { public: + // 小顶堆 class mycomparison { public: bool operator()(const pair& lhs, const pair& rhs) { - return lhs.second < rhs.second; + return lhs.second > rhs.second; } }; - // 如何定义priQue - // 如何定义cmp - // 如何遍历map vector topKFrequent(vector& nums, int k) { - unordered_map map; + // 要统计元素出现频率 + unordered_map map; // map for (int i = 0; i < nums.size(); i++) { map[nums[i]]++; } - // greater> 也可以 - priority_queue, vector>, mycomparison> pri_que; - // 当然可以使用auto + // 对频率排序 + // 定义一个小顶堆,大小为k + priority_queue, vector>, mycomparison> pri_que; for (unordered_map::iterator it = map.begin(); it != map.end(); it++) { pri_que.push(*it); + if (pri_que.size() > k) { + pri_que.pop(); + } } - // 一开始就确定空间 + + // 找出前K个高频元素 vector result(k); - for (int i = 0; i < k; i++) { + for (int i = k - 1; i >= 0; i--) { result[i] = pri_que.top().first; pri_que.pop(); } @@ -38,5 +51,9 @@ public: } }; +// 时间复杂度:O(nlogk) +// 空间复杂度:O(n) ``` +> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。 +