思路:维护一个长度为k的单调双端队列,队首元素为最大或最小值的下标。
滑动窗口中求最大值或最小值的区别在代码上只有一个符号之差。
#include <iostream>
#include <queue>
using namespace std;
const int N = 1e6 + 10;
int n, k;
int nums[N];
int main()
{
cin >> n >> k;
for (int i = 0; i < n; i ++ ) cin >> nums[i];
deque<int> q; //双端队列 q 存下标
for (int i = 0; i < n; i ++ ) //求滑动窗口最小值
{
if (q.size() && q.front() <= i - k) q.pop_front(); //滑出窗口
//滑动窗口中最大最小值的区别只在于下一行代码中是用 >= 还是用 <= 做判断。
while (q.size() && nums[q.back()] >= nums[i]) q.pop_back(); //维护队列单调性
q.push_back(i);
if (i >= k - 1) printf("%d ", nums[q.front()]); //最大值请入res
}
puts("");
q.clear(); //清空队列
for (int i = 0; i < n; i ++ ) //求滑动窗口最大值
{
if (q.size() && q.front() <= i - k) q.pop_front();
while (q.size() && nums[q.back()] <= nums[i]) q.pop_back();
q.push_back(i);
if (i >= k - 1) printf("%d ", nums[q.front()]);
}
return 0;
}