解法:单调队列充当滑动窗口
思想:
- 构造一个从队头到队尾单调递减的双向队列
- 从队尾加入元素,将队列中所有比新元素值小的元素移除,再放入新元素
- 每次移除队头元素要判断队头元素是否是该被移除的元素(在维护单调队列的过程中可能已经被移除了)
- 以上就是窗口滑动的过程
- 队头一定是当前窗口内的最大值
- 首先处理第一个窗口然后再开始滑动,这样就不用考虑窗口大小是否会超过k,直接进行处理逻辑比较简单
代码:
deque<int> dq;
void push(int num)
{
while (!dq.empty() && num > dq.back())
{
dq.pop_back();
}
dq.push_back(num);
}
void pop(int num)
{
if (num == dq.front())
{
dq.pop_front();
}
}
int getMax()
{
return dq.front();
}
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
// 首先处理第一个窗口
for (int i = 0; i < k; i++)
{
push(nums[i]);
}
res.push_back(getMax());
// 窗口移动
for (int i = k; i < nums.size(); i++)
{
pop(nums[i - k]);
push(nums[i]);
res.push_back(getMax());
}
return res;
}