题目
给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
思路
要解决这个问题,可以使用双端队列(deque)。双端队列可以在两端进行插入和删除操作,非常适合用于滑动窗口问题。
以下是解决该问题的思路:
- 首先创建一个双端队列
dq
,用于存储数组元素的索引。 - 初始化结果数组
result
和左右指针left
和right
。 - 遍历数组
nums
,对于每个元素nums[right]
,执行以下操作:- 在队列
dq
的尾部插入元素索引right
。但在插入之前,需要先将队列中比当前元素小的元素索引移除,因为它们不可能成为最大值。 - 判断队列头部的元素索引是否已经超出滑动窗口范围
left
,如果是则移除队首元素。 - 判断当前元素索引是否已经超过了滑动窗口的大小
k
,如果是,则表示当前窗口已经完整形成,可以记录当前窗口的最大值,即数组nums[dq.front()]
,并将其存入结果数组result
中。 - 将右指针
right
向右移动一位,继续遍历下一个元素。
- 在队列
- 返回结果数组
result
。其中,result
的长度为nums.size() - k + 1
,即滑动窗口的总数。
Code
#include <deque>
#include <vector>
std::vector<int> maxSlidingWindow(std::vector<int>& nums, int k) {
std::vector<int> result;
std::deque<int> dq;
int left = 0, right = 0;
while (right < nums.size()) {
// 在队列尾部插入元素索引,移除比当前元素小的索引
while (!dq.empty() && nums[dq.back()] < nums[right]) {
dq.pop_back();
}
dq.push_back(right);
// 移除超出滑动窗口范围的索引
if (dq.front() < left) {
dq.pop_front();
}
// 记录当前窗口的最大值
if (right - left + 1 == k) {
result.push_back(nums[dq.front()]);
left++;
}
right++;
}
return result;
}
这段代码通过遍历数组,维护一个双端队列,实现了在滑动窗口中找到最大值的功能。