题目:
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
示例 2:
输入: nums = [1], k = 1 输出: [1]
思路
- 先用unordered_map存储每个元素出现的次数,即ump[ nums [ i ] ] ++;
- 在构建小根堆(优先队列,priority_queue),记得构造比较类
- 把元素放入小根堆后,到元素>k个时,再自动弹出元素,保证小根堆元素只有k个
- 最后,把元素放入到答案数组中
代码
//用priority_queue + unordered_map解决问题
//step1 统计元素出现的次数
//step2 放入priority_queue
//step3 取出元素
class Solution {
public:
class Compare{
public:
bool operator()(const pair<int,int> &L,const pair<int,int> &R)const
{
return L.second>R.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> ump;
//统计
for(int i=0;i<nums.size();i++)
{
ump[nums[i]]++;
}
//放入小根堆
priority_queue<pair<int,int>,vector<pair<int,int>>,Compare> pri_que;
for(unordered_map<int,int>::iterator it = ump.begin();it!=ump.end();it++)
{
//放入小根堆
pri_que.push(*it);
//当小根堆里面超过k个元素时,弹出较小的元素 这就是为什么要用小根堆的原因了
//方便弹出元素
if(pri_que.size()>k)
{
pri_que.pop();
}
}
//构建k个元素的答案数组
vector<int> ans(k);
//从后往前放入元素
for(int i=k-1;i>=0;i--)
{
//ans.push_back(pri_que[i].first);
ans[i]=pri_que.top().first;
pri_que.pop();
}
return ans;
}
};
知识点:
- priority_queue的使用
- 包含<queue>的头文件
- 要记得写自己的比较类
//小根堆 class mycomparison { public: bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) { return lhs.second > rhs.second; } }; //这里 > 号 表示小根堆 即 小的元素在堆顶 // < 号表示大根堆
- 关于优先队列的构造
- priority_queue<数据类型,vector<数据类型>,compare类>
- 例:priority_queue<int,vector<int>,compare> pri_que;
- priority_queue<数据类型,vector<数据类型>,compare类>
- 关于优先队列常见函数的使用
- priority_queue(InputIterator first, InputIterator last,
const Compare& comp = Compare(),
const Container& ctnr = Container()); 区间构造函数
push(const value_type& val) 插入元素
void pop() 删除队头元素
const value_type& top() const 返回队头元素的引用(队头元素不可以修改,队头元素也就是堆顶元素)
bool empty() const 判断队列是否是空
- priority_queue(InputIterator first, InputIterator last,
- unordered_map的使用