剑指 Offer 59 - I. 滑动窗口的最大值
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
示例:
输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。
题解
单调队列,每次维护一个从大到小的单调队列,队首最大,队尾最小,队列严格单调递减
入队操作:加入一个元素前,比较队尾,如果队尾元素比这个元素小,那么求窗口最大值时,这个元素永远不会被用到
将其队尾元素弹出,重复此操作,直至找到一个大于这个元素的值,然后再将元素插入,保证这个队列单调递减
取值操作:每次滑动后,紧接着入队操作,然后取值记录这个窗口的最大值,即队首元素
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if(nums.size()==0) return vector<int>();
int hh = 0, tt = -1;
int n = nums.size();
vector<int> ans;
vector<int> q(n, 0);
for(int i=0; i<nums.size(); ++i){
if(hh<=tt && i-k+1 > q[hh]) hh++;
while(hh<=tt && nums[i]>=nums[q[tt]]) tt--;
q[++tt] = i;
if(i >= k-1){
ans.push_back(nums[q[hh]]);
}
}
return ans;
}
};