主要思路
利用一个单调队列维护当前窗口最小值,然后再维护最大值
代码
#include <bits/stdc++.h>
using namespace std;
int main(void) {
int n, k;
cin >> n >> k;
int a[n];
for(int i = 0; i < n; i++) {
cin >> a[i];
}
deque<int> q;
//输出最小值,单调队列里维护的是非递减数列
for(int i = 0; i < k; i++) { //第一个窗口里最小值
while(!q.empty() && a[i] < q.back()) {
q.pop_back();
}
q.push_back(a[i]);
}
cout << q.front() << ' ';
for(int i = k; i < n; i++) { //a[i]代表新加入滑动窗口的元素
if(q.front() == a[i - k]) { //a[i - k]表示当前滑动窗口第一个元素前一个元素
q.pop_front(); //先要去头
}
while(!q.empty() && a[i] < q.back()) { //再去尾
q.pop_back();
}
q.push_back(a[i]);
cout << q.front() << ' ';
}
cout << endl;
//输出最大
while(!q.empty()) q.pop_back();
for(int i = 0; i < k; i++) {
while(!q.empty() && a[i] > q.back()) {
q.pop_back();
}
q.push_back(a[i]);
}
cout << q.front() << ' ';
for(int i = k; i < n; i++) {
if(q.front() == a[i - k]) {
q.pop_front();
}
while(!q.empty() && a[i] > q.back()) {
q.pop_back();
}
q.push_back(a[i]);
cout << q.front() << ' ';
}
return 0;
}
第一次写错误
单调队列特点都是要“斩头去尾”,其中“斩头”放在“去尾”前,且是在当前滑动窗口已滑至下一位,即单调队列里维护的第一位已经不在当前滑动窗口里了