给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 。
class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> result;deque<int> dq; // 双端队列,用来存储窗口中元素的索引for (int i = 0; i < nums.size(); ++i) {// 移除不在窗口范围内的元素if (!dq.empty() && dq.front() < i - k + 1) {dq.pop_front();}// 移除所有小于当前元素的值,它们不可能成为窗口的最大值while (!dq.empty() && nums[dq.back()] < nums[i]) {dq.pop_back();}// 将当前元素的索引加入队列dq.push_back(i);// 窗口形成后(即 i >= k - 1),记录窗口的最大值if (i >= k - 1) {result.push_back(nums[dq.front()]);}}return result;}
};
双端队列维护窗口最大值:
双端队列存储的是元素的索引,而不是值。
保证队列中索引对应的值是递减的,从而队列头部始终是窗口内的最大值。
窗口的更新:
移除队列中不在当前窗口范围内的元素。
移除队列中所有小于当前值的元素,因为它们不可能成为当前窗口的最大值。
记录最大值:
每次移动窗口时,将队列头部的值(即当前窗口的最大值)加入结果。
双端队列的性质:
队列中的元素从头到尾递减。
队列头部始终是当前窗口的最大值。
滑动窗口逻辑:
当窗口左边界超出队列中最左边的索引时,移除队列头部。
插入新元素之前,移除队列中所有小于当前值的元素。
结果记录:
当窗口的右边界到达 k−1k - 1k−1 或之后时,窗口形成,记录最大值。