https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/

思路:单调队列。顾名思义,具有单调性的队列。比如这道题,我们可以维护一个单调递减的队列,即保证最大值在队首,那么就可以在 O ( 1 ) O(1) O(1)内找到滑动窗口的最大值。但是光维护单调性是不行滴,因为滑动窗口有大小限制呀,比如这道题就是 k k k,那么我们需要计算当前位置与队首元素所在位置的索引差,看它与 k k k的大小关系,如果超过了 k k k,就需要弹出队首的元素。思路有了,怎么实现呢? ( 1 ) (1) (1)既然同时需要索引和值,不如搞一个 p a i r pair pair同时存储这两个数据,再放到队列里就行了。 ( 2 ) (2) (2)已知索引和原数组,那么值很容易获得,所以可以直接搞一个队列,里面放索引就完事了。下面的代码用的就是后面的办法。
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> ans;
int siz=nums.size();
if(!siz)
return ans;
//arr存储下标 维护单调非升队列
int arr[siz];
//队头队尾
int fon=0,bak=0;
for(int i=0;i<k;i++){
//队列非空 维护单调非升这一性质
while(fon<bak&&nums[i]>nums[arr[bak-1]])
--bak;
arr[bak++]=i;
}
ans.push_back(nums[arr[fon]]);
for(int i=k;i<siz;i++){
//超出滑动窗口的大小k 需要进行出队操作
if(i-arr[fon]+1>k)
++fon;
//同上
while(fon<bak&&nums[i]>nums[arr[bak-1]])
--bak;
arr[bak++]=i;
ans.push_back(nums[arr[fon]]);
}
return ans;
}
};
啥?不想手写队列,那就用 d e q u e deque deque吧。
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> ans;
int siz=nums.size();
if(!siz)
return ans;
deque<int> q;
for(int i=0;i<k;i++){
while(!q.empty()&&nums[i]>nums[q.back()])
q.pop_back();
q.push_back(i);
}
ans.push_back(nums[q.front()]);
for(int i=k;i<siz;i++){
//超出滑动窗口的大小k 需要进行出队操作
if(i-q.front()+1>k)
q.pop_front();
//同上
while(!q.empty()&&nums[i]>nums[q.back()])
q.pop_back();
q.push_back(i);
ans.push_back(nums[q.front()]);
}
return ans;
}
};
15万+




被折叠的 条评论
为什么被折叠?



