1.滑动窗口的最大值(等价于实现max函数的队列
题目描述:给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
难度:困难
示例:来自力扣示例
剑指offer59/力扣239
题解:
我们先看一道包含min函数的栈。
题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
class MinStack {
private:
stack<int> stack1,stack2;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
stack1.push(x);
if(stack2.empty()||stack2.top()>=x)
stack2.push(x);
}
void pop() {
if(stack1.top()==stack2.top())
stack2.pop();
stack1.pop();
}
int top() {
return stack1.top();
}
int min() {
return stack2.top();
}
};
能返回最小值的栈的思路为,除保存所有元素的栈之外,再增加一个非严格单调递减的辅助栈,这样每次返回辅助栈的top元素,即为栈中最小的元素的值,在栈删除元素的时候,比较是否跟辅助栈的top元素相等,如果相等,将辅助栈top元素弹出,栈插入元素时,比较是否小于等于辅助栈栈顶元素,如果小于等于则将其加入辅助栈。
本题实际上可以理解为实现一个能返回最大值的队列,滑动窗口没滑动一次,队列就pop一次,push一次,并且返回当前队列当中的最大值。
class maxQueue{
queue<int> q;
deque<int> maxq;
public:
void push_back(int n){
q.push(n);
if(maxq.empty()||maxq.front()>=n){
while(!maxq.empty()&&maxq.back()<n)
maxq.pop_back();
maxq.push_back(n);
}
else{
maxq.clear();
maxq.push_back(n);
}
}
void pop(){
int temp=q.front();
q.pop();
if(temp==maxq.front())
maxq.pop_front();
}
int getmax(){
return maxq.front();
}
};
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
int n=nums.size();
if(n==0)
return {};
vector<int> ans;
maxQueue q;
for(int i=0;i<k;i++)
q.push_back(nums[i]);
ans.push_back(q.getmax());
for(int i=k;i<n;i++){
q.pop();
q.push_back(nums[i]);
ans.push_back(q.getmax());
}
return ans;
}
};
本题为返回最大值的队列,我们除保存所有元素的队列之外,再增加一个非严格单调递减的辅助双向队列,每次返回辅助队列的front元素,即为队列中最大的元素的值。队列插入元素时,比较其与辅助队列front元素的大小,如果小于等于,则从后向前删除辅助队列元素,直到辅助队列为空,或队列尾部元素大于等于新插元素大小,将新插元素加入辅助队列末尾;如果大于,则将辅助队列清空,将新插元素插入队列。