代码随想录Day 11 栈与队列
C++中优先级队列
优先级队列是一种特殊的队列,其具有队列的所有特性和基本操作,包括:
top: 访问队列头元素
push: 将元素插入到队尾 并排序
pop: 弹出队列头元素
empty: 判断队列是否为空
size: 获取队列元素个数
emplace: 原地构造一个元素并插入队列
swap: 交换内容
其声明方式为:priority_queue<Type, Container, Functional> queue_name
,其中Type
为队列中存放的数据类型,(Container
是容器类型(Container必须是用数组实现的容器,比如vector, deque等,不能用list。 STL默认vector)```Functional``为比较方式,可以不指定这个参数,默认是大顶堆。
// 升序队列 小顶堆
priority_queue<int, vector<int>, greater<int>> que;
// 降序队列 大顶堆
priority_queue<int, vector<int>, less<int>> que;
239滑动窗口最大值
class Solution {
private:
class Dequeue{
public:
deque<int> que;
void pop(int value){
//由于队列里严格单调递减的,队列中当前元素不存在相等的情况
// 判断队列头元素是否是要移出滑动窗口的元素
if(!que.empty() && value == que.front()){
que.pop_front();
}
}
void push(int value){
// 每次在队列中加入一个元素时,移出队列中比这个元素要大的所有元素
while(!que.empty() && value > que.back()){
que.pop_back();
}
que.push_back(value);
}
int front(){
//队列头元素是当前滑动窗口中的最大值
return que.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> result;
Dequeue que;
//先添加前k个元素,形成滑动窗口
for(int i = 0; i < k; i++){
que.push(nums[i]);
}
//将第一个滑动窗口的最大值存入result中
result.push_back(que.front());
//移动滑动窗口,遍历数组中剩余的元素
for(int i = k; i < nums.size(); i++){
//que队列中理论上已经添加过了k个元素,因此先执行pop操作
//当窗口滑动到下标i时,被滑出的元素的下标是i-k
que.pop(nums[i-k]);
que.push(nums[i]);
result.push_back(que.front());
}
return result;
}
};
347前K个高频元素
这道题要求获得前K个高频元素,注意不要使用大顶堆,如果使用大顶堆,那么最后队列中留下的是前K个最低频的元素。
class Solution {
public:
class comparison {
public:
bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {
return lhs.second > rhs.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> fre;
for(int i = 0; i < nums.size(); i++){
fre[nums[i]] ++;
}
//定义一个大小为k的小顶堆
priority_queue<pair<int,int>, vector<pair<int,int>>, comparison> que;
for(unordered_map<int, int>::iterator it = fre.begin(); it != fre.end(); it++){
que.push(*it);
//只维护k个元素
if(que.size() > k){
que.pop();
}
}
vector<int> result(k);
while(k--){
result[k] = que.top().first;
que.pop();
}
return result;
}
};