239 滑动窗口最大值
题干
思路
想到利用队列解决,但是想不出移除元素后如何快速得到当前窗口的最大值
解决方法
- 构造自己的队列形式
- 单调队列,即单调递减或单调递增的队列,在移除数字等同于先前窗口最大值的情况下,仍能返回新窗口下的最大值
队列的基本使用
deque<int> que;//定义
que.pop_back(); //弹出队列尾元素
que.pop_front();//弹出队列头元素
que.push_back(value);//压入元素进队尾
que.front();//得到队列头元素
实现
- 重点:push()和pop()函数的涉及!!!
class Solution {
private:
class myque{
public:
deque<int> que;
void push(int value){
while(!que.empty()&&value>que.back()){
que.pop_back();
}
que.push_back(value);
}
void pop(int value){
if(!que.empty()&&value==que.front()){
que.pop_front();
}
}
int front(){
return que.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
//20240321keep moving fighting
myque que;
vector<int> ans;
for(int i=0;i<k;i++){
que.push(nums[i]);
}
ans.push_back(que.front());
for(int i=k;i<nums.size();i++){
que.push(nums[i]);
que.pop(nums[i-k]);
ans.push_back(que.front());
}
return ans;
}
};
347 前k个高频元素
题干
思路
- 统计各元素出现频率
- 对各频率进行排序
- 得到前k个元素
~~ 思路是想明白了,但是在后面两点实现上存在困难,会很麻烦,因为是对map的值进行排序,但是返回的是index,同时取前k个会比较麻烦,困在这里了~~
要点
- 优先级队列priority_queue,内部自动按照元素权值排序,实际上是一种堆
- 堆是一种完全二叉树
- 大顶堆 父亲结点是大于等于左右孩子
- 小顶堆 父亲节点小于等于左右孩子
优先级队列的基本使用
priority_queue<pair<int,int>,vector<pair<int,int>>,mycompare> prique;//定义
mycompare;//是一种比较形式,决定是大顶堆还是小顶堆
prique.push(value);//压入元素
prique.pop();//弹出元素
prique.top();//得到堆顶元素
遍历map的基本操作
for(unordered_map<int,int>::iterator it=map.begin();it!=map.end();it++){
*it.first;//频次对应的元素
*it.second;//频次
}
//在这里的代码中,map频次及元素组成pair,不知道理解对不对
pair<int,int>;
代码
class Solution {
class mycompare{
public:
bool operator()(const pair<int,int>&l,const pair<int,int>&r){
return l.second>r.second;
}
};
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> map;
for(int i=0;i<nums.size();i++)
map[nums[i]]++;
//排序
//定义小顶堆
priority_queue<pair<int,int>,vector<pair<int,int>>,mycompare> prique;
//利用小顶堆扫描所有频率的数值
for(unordered_map<int,int>::iterator it=map.begin();it!=map.end();it++){
prique.push(*it);
if(prique.size()>k){
prique.pop();
}
}
vector<int> ans(k);
for(int i=k-1;i>=0;i--){
ans[i]=prique.top().first;
prique.pop();
}
return ans;
}
};
堆栈总结
- 栈是容器适配器,底层容器使用不同的容器,导致栈内数据在内存中不一定是连续分布的。
- 缺省情况下,默认底层容器是deque,deque在内存中的数据分布是不连续的。
- 递归的实现是栈:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,递归可以返回上一层位置的原因。
- ,C++中deque是stack和queue默认的底层实现容器,deque可以两边扩展,而且deque里元素并不是严格的连续分布的。