[刷题] 347 Top K Frequent Elements

要求

  • 给定一个非空数组,返回前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 };
View Code

相关

  • 23 Merge k Sorted Lists

参考

  • c++优先队列(priority_queue)用法详解
  • https://www.cnblogs.com/huashanqingzhu/p/11040390.html
原文地址:https://www.cnblogs.com/cxc1357/p/12664381.html