
解法1:暴力法
思想:
遍历每个滑动窗口,找出其中的最大值
复杂度:
●时间:O((N - k + 1)k) = O(Nk),每个窗口k个数,总共有N - k + 1个窗口
●空间:
解法2:单调队列
https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/solution/mian-shi-ti-59-i-hua-dong-chuang-kou-de-zui-da-1-6/
思想:
用deque维护一个非严格递减的单调队列,队首就是当前滑窗内的最大元素
1.当从左出窗口的元素恰好是队首元素,pop_front(),因为是非严格递减,所以队首元素重复也不会出问题
2.从尾插入新的nums[right]时要把小于它的全部pop_back(),来维持非严格递减
3.队首元素加入res
复杂度:
●时间:O(N),每个元素最多入队出队一次,O(2N) = O(N)
●空间:O(k),同时存储k个元素
代码注意点:
●deque[0]即deque.front() ,deque[deque.size() - 1]即deque.back()
●先处理左边的出队,再处理右边的入队,再处理res数组
●最后移动left和right
代码:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if(nums.size() == 0 || k == 0)
return {};
deque<int>deque;
vector<int>res;
int left = 1 - k, right = 0;
while(right < nums.size()){
//当left端出滑窗的元素刚好是最大的元素时,出队
if(left >= 1 && nums[left - 1] == deque[0])
deque.pop_front();
//从尾端将小于新元素的元素出队,维持非严格递减
while(!deque.empty() && deque.back() < nums[right])
deque.pop_back();
//加入新元素
deque.push_back(nums[right]);
//left >= 0即形成滑窗,开始将结果加入res
if(left >= 0)
res.push_back(deque[0]);
//移动left和right
++left;
++right;
}
return res;
}
};
本文介绍了解决滑动窗口最大值问题的两种方法:暴力法和单调队列法,并详细解析了单调队列法的实现原理及代码细节。
218

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



