priority_queue的定义
优先级队列不同于普通的queue,他是按照优先级的顺序排队。
可以想象成 一个队伍 vip永远在前面,普通游客只能在vip后面。vip也分3 6 9 等;
并且这个队列会自动排序。
如果此时有一个新的vip加入,不是根据queue的原则先进先出。新vip将会直接根据优先级排在普通游客前面。然会根据它的vip等级 在一众vip游客中 插入 他的位置;
创建优先队列
priority_queue<int,vector<int>,less<>> q;
priority_queue<int,vector<int>,greater<>> q1;
第一个表示优先队列存放的类型
第二个Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector)
第三个则是非常重要的一部分 单独讲述
less greater
如果存放的类似于int string double 这些基本数据类型 那么你可以直接使用less<> greater<>
第三个参数 很方便。
但是请注意 一定搞清楚哪一个是大顶堆 哪一个是小顶堆
less 是 return a<b greater return a>b
请注意的是 这里的大小比较很多人会困惑 为什么小于号是大顶堆 大于号是小顶堆
这里我们可以记住 优先队列中 我们采用的优先级排序 而优先队列他是从 排序的尾巴开始
也就是优先级最大的开始 a<b a的优先级小于b 所以最大的也在最后面 而最后面的优先级最大
所以是大顶堆
同理 a>b b的优先级在最后 也就是最小的数 所以这是小顶堆
仿函数
首先 这个名字听起来很古怪。是的,他类似函数 但不是函数。
实际上他是一个类 只不过重写了operator()方法
仿函数的具体内容不拓展 只需要记住 他是一个类 然后重写了operator()方法 类似于sort中的重写一个cmp比较函数而已
例题前k个高频元素
这题首先需要搞清楚我们需要大顶堆还是小顶堆,高频元素 前几个 很容易错想到大顶堆
请注意 大顶堆是大的优先级高不错 但是优先级高的是弹出去的 不是保存的
如果大顶堆 我们怎么知道前k个高频元素
所以这题我们需要小顶堆 保留大的数据 弹出小的
而且我们的数据类型是pair<int,int>
我们第三个参数选择的是 仿函数方法
class sure{
public:
bool operator()(const pair<int,int> &a,const pair<int,int> &b){
return a.second>b.second;
}
};
而且 讲过 涉及到 一个元素的两个数据 高频元素 什么元素 有多少次频类 就涉及到map
vector<int> topKFrequent(vector<int>& nums, int k) {
priority_queue<pair<int,int>,vector<pair<int,int>>,sure> que;
unordered_map<int,int> umap;
for(int it:nums)umap[it]++;
for(auto it : umap){
que.push(it);
if(que.size()>k)que.pop();
}
vector<int> ans;
while(!que.empty()){
ans.push_back(que.top().first);
que.pop();
}
return ans;
}
代码不难 这题涉及到的就是优先队列的使用 我们需要分清楚到底是小顶堆 还是大顶堆
其余的话是 水到渠成