347. 前 K 个高频元素
题目描述:
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
 
提示:
你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
你可以按任意顺序返回答案。
思想:
思路一:使用hashmap统计nums中数字的出现次数,然后按value进行排序,返回前k项,注意map的排序要借助vector,时间复杂度与空间复杂度较高
思路二:
- 利用hashmap统计元素出现的频次,建立元素与频次之间的映射
- 创建元素个数为k的小顶堆优先队列
- 遍历hashmap, 当优先队列中元素个数小于k时,直接加入优先队列
- 如果优先队列中元素个数等于k时,新元素的频次与堆顶元素频次比较,如果比堆顶元素频次高,pop出堆顶元素,然后再push新的元素,如果比堆顶元素频次还要低,则不处理
- 最后使用数组保存频次前k的元素
思路一代码:
class Solution { public: vector<int> topKFrequent(vector<int>& nums, int k) { map<int,int>m; for(auto num : nums) // 存到哈希结构里 m[num]++; vector<pair<int,int >>v; vector<int>ans; for(auto it : m) // 存到用于对value排序的容器里 v.push_back(make_pair(it.first,it.second)); sort(v.begin(),v.end(),[](pair<int,int> &a,pair<int,int> &b)->bool{return a.second>b.second;}); // 对容器中的pair按照出现次数从大到小排序 /* C++ 的lambda表达式和java的略有区别 */ for(int i=0;k;++i,--k) ans.push_back(v[i].first); return ans; } };
思路二代码:
class Solution { public: struct cmp { bool operator()(const pair<int, int> &left, const pair<int, int> &right) { return left.second > right.second; } }; vector<int> topKFrequent(vector<int>& nums, int k) { unordered_map<int, int> mp; for (auto i : nums) { mp[i]++; } priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> q; // 创建一个小顶堆 for (auto item : mp) { if (q.size() < k) { q.push(item); } else if (item.second > q.top().second) { q.pop(); q.push(item); } // 新的元素频次小于堆顶元素频次的元素不处理。 } vector<int> res(q.size(), 0); while (!q.empty()) { res[q.size()-1] = q.top().first; q.pop(); } return res; }; };
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号