要求
- 给定一个非空数组,返回前k个出现频率最高的元素
示例
- [1,1,1,2,2,3], k=2
- 输出:[1,2]
思路
- 出队逻辑,普通队列是先进先出,优先队列是按最大/最小值出队
- 通过堆实现优先队列,C++中用 priority_queue<Type, Container, Functional>
- 扫描一遍统计频率,排序找前k个出现频率最高的元素(nlogn)
- 维护一个含有k个元素的优先队列,遍历到的元素比队列中的最小频率元素的频率高,则取出最小频率的元素,将新元素入队(nlogk)
实现
- 扫描数组,用 unordered_map 统计频率
- 维护k个元素的优先队列,priority_queue<类型,容器,比较方式>,其中数据类型为pair<频率,元素>
- 对于pair默认先比较第一个元素,第一个元素相等再比较第二个
1 class Solution { 2 public: 3 vector<int> topKFrequent(vector<int>& nums, int k) { 4 assert( k > 0 ); 5 6 unordered_map<int ,int > freq; 7 for( int i = 0 ; i < nums.size() ; i ++ ) 8 freq[nums[i]] ++; 9 assert( k <= freq.size() ); 10 11 // 优先队列中,数据对是(频率,元素)的形式 12 priority_queue< pair<int,int> , vector<pair<int,int>>, greater<pair<int,int>>> pq; 13 for( unordered_map<int,int>::iterator iter = freq.begin() ; 14 iter != freq.end() ; iter ++){ 15 if(pq.size() == k ){ 16 if( iter->second > pq.top().first){ 17 pq.pop(); 18 pq.push( make_pair( iter->second, iter->first ) ); 19 } 20 } 21 else 22 pq.push( make_pair( iter->second, iter->first ) ); 23 } 24 25 vector<int> res; 26 while( !pq.empty() ){ 27 res.push_back( pq.top().second ); 28 pq.pop(); 29 } 30 return res; 31 } 32 };
相关
- 23 Merge k Sorted Lists
参考
- c++优先队列(priority_queue)用法详解
- https://www.cnblogs.com/huashanqingzhu/p/11040390.html