题目链接:https://leetcode.cn/problems/sliding-window-maximum/
思路如下:
使用双端队列维护一个单调队列。首先要明确的是,双端队列中存放的是索引。同时,要时刻保证队列中的索引对应的数组元素值从头到尾是逐渐减小的。
ri
用于从左往右依次遍历 nums 数组,同时 ri
也是滑动窗口的最右索引。
li
是滑动窗口的最左索引,即 li = ri - k + 1
。
求滑动窗口最大值的步骤如下:
-
如果
nums[ri] >= nums[队尾]
,则不断删除队尾,直到nums[队尾] > nums[ri]
为止。 -
将
ri
加入队尾。 -
当
li < 0
的时候,意味着此时还没有出现一个完整的滑动窗口,直接跳过即可。 -
当
li >= 0
的时候,如果队头过期,就移除队头,然后记录此时滑动窗口的最大值为nums[队头]
。
C++代码如下:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
int n = nums.size();
vector<int> res(n - k + 1);
deque<int> q;
for (int ri = 0; ri < n; ri++) {
// 如果nums[ri] >= nums[队尾],则不断删除队尾
while (!q.empty() && nums[ri] >= nums[q.back()]) {
q.pop_back();
}
// 将ri加入队尾
q.push_back(ri);
int li = ri - k + 1;
// 当li < 0的时候,意味着此时还没有出现一个完整的滑动窗口,直接跳过即可
if (li < 0) {
continue;
}
// 如果队头过期,就移除队头
if (q.front() < li) {
q.pop_front();
}
// 记录此时滑动窗口的最大值为nums[队头]
res[li] = nums[q.front()];
}
return res;
}
};