您的位置:首页 > 产品设计 > UI/UE

LeetCode 347. Top K Frequent Elements 优先队列的使用及注意事项

2017-05-26 17:38 477 查看
Top K Frequent Elements
题意

注意

思路

代码

结果

优先队列的使用

347. Top K Frequent Elements

Given a non-empty array of integers, return the k most frequent elements.

For example,

Given [1,1,1,2,2,3] and k = 2, return [1,2].

Note:

You may assume k is always valid, 1 ≤ k ≤ of unique elements.

Your algorithm’s time complexity must be better than O(n log n), where n is the array’s size.

题意

给定一个非空的整型数组,返回出现频率次数排在前k的元素

注意

k的有效性。

题目已经给出k总是有效的,并且是唯一的

算法时间复杂度必须是O(nlogn)的

思路

扫描一遍统计频率;排序找到前k个出现频率最高的元素。 O(nlogn)

维护一个含有k个元素的优先队列。如果遍历到的元素比队列中的最小频率元素的频率高,则取出队列中最小频率的元素,将新元素入队。最终,队列中剩下的,就是前k个出现频率最高的元素。维护优先队列,时间复杂度:O(nlogk)

代码

class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> freq;
for(auto temp:nums)
freq[temp]++;
//应该也是存储了两个元素<频率,元素>
// priority_queue<pair<int,int>> que;   //注意priority_queue没有迭代器,queue没有迭代器
//priority_queue默认使用最大堆,而我们希望队头元素是频率最小的元素,所以应该还是最小堆
//总是弹出最大元素或者最小元素
//需要和存储类型配套使用
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int> >> que;
for(auto iter = freq.begin();iter != freq.end();iter++)
{
//优先队列的长度一直维持在k
if(que.size() == k)
{
//que通过top函数得到的是一个pair。还需要取具体元素
if(que.top().first < iter->second)
{
que.pop();         //当最小的频率比当前的频率低,需要弹出最小元素
que.push(make_pair(iter->second,iter->first));
}
}
else
que.push(make_pair(iter->second,iter->first));
}

vector<int> res;
while(!que.empty())
{
res.push_back(que.top().second);
que.pop();
}
return res;

}
};


结果



优先队列的使用

优先队列的底层实现缺省状态是最大堆,所以加入优先队列的元素是从大到小排序的

通过定义可以使用最小堆实现的优先队列



注意,优先队列出队没有front操作,只有top操作。

队列的遍历也需要注意只能每次取队头元素然后弹出,在取队头元素,在弹出。

具体看《STL源码解析》第四章。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: