题目描述:
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
示例:
输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7]
解释:
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。
方法1:
主要思路:
(1)主要是使用双向队列,将当前窗口内的值从队尾放入,若当前值小于等于队尾的值,则直接放入,若当前值大于队尾的值,就从队尾弹出元素,直到能够放入;
(2)从窗口内找最大值的时候,直接从对头取值,同时比较窗口的左边界left对应的值是否是当前对头的值,若是,则将对头的值弹出,以保证后续窗口内的最大值依旧是对头的值;
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
//处理特殊的情形
if(nums.empty()||k==0){
return {};
}
deque<int> q;
//初始化对内元素
for(int i=0;i<k;++i){
while(!q.empty()&&nums[i]>q.back()){
q.pop_back();
}
q.push_back(nums[i]);
}
//特殊情形
if(k==nums.size()){
return {q.front()};
}
//窗口的左右边界
int left=0;
int right=k;
vector<int> res;
while(right<nums.size()){
res.push_back(q.front());//取出当前窗口内的最大值
//考虑是否弹出当前对头的值,既当前对头的值是否要跳出窗口范围
if(q.front()==nums[left]){
q.pop_front();
}
++left;//调整窗口左边界
//压入新的窗口的元素,保证当前窗口的最大值在对头前面
while(!q.empty()&&q.back()<nums[right]){
q.pop_back();
}
q.push_back(nums[right]);
++right;//调整右边界
}
res.push_back(q.front());//压入最后一个窗口内的最大值
return res;
}
};