思路:用数组模拟单调栈,qh表示队头,qt表示队尾,从朴素算法中找到单调性的规律。
using i64 = long long;
const int N = 1000000;
int n, k;//表示数组长度和窗口的长度。
int a[N], q[N];//表示原数组和模拟队列的数组且队列数组里存的是原数组的下标。
int qh = 0, qt = -1;//表示队头下标和队尾下标。
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> k;
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
for (int i = 0; i < n; i++) {
if (qh <= qt && i - k + 1 > q[qh]) {
qh++;
}//判断队头元素是否弹出维护的区间。
while (qh <= qt && a[q[qt]] >= a[i]) {
qt--;
}//解决队尾与当前元素a[i]不满足单调性的问题。
q[++qt] = i;//进队。
if (i >= k - 1) {
std::cout << a[q[qh]] << " \n"[i == n - 1];//输出最小值。
}
}
qh = 0, qt = -1;
for (int i = 0; i < n; i++) {
if (qh <= qt && i - k + 1 > q[qh]) {
qh++;
}//判断队头元素是否弹出维护的区间。
while (qh <= qt && a[q[qt]] <= a[i]) {
qt--;
}//解决队尾与当前元素a[i]不满足单调性的问题。
q[++qt] = i;//进队。
if (i >= k - 1) {
std::cout << a[q[qh]] << " \n"[i == n - 1];//输出最大值。
}
}
return 0;
}