题目链接:
题意:
给 n, k,n 个数字,求所有长度为 k 的区间的最小值和最大值
做法:
单调队列,考虑维护一个单调递增/减的队列,并用滑动窗口的方法使得队列的首尾位置相差<=k,这样每次队首的位置都是长度为 k 的区间的最大/小值
代码:
#include <bits/stdc++.h>
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
deque<int>q1, q2;
//q1 单调增 q2 单调减
int a[1000005];
int main()
{
int n, k, t;
sc("%d%d", &n, &k);
vector<int>ans1, ans2;
for (int i = 1; i <= n; i++)
{
sc("%d", &a[i]);
while (!q1.empty() && q1.front() + k <= i)
q1.pop_front();
while (!q1.empty() && a[q1.back()] > a[i])
q1.pop_back();
while (!q2.empty() && q2.front() + k <= i)
q2.pop_front();
while (!q2.empty() && a[q2.back()] < a[i])
q2.pop_back();
q1.push_back(i);
q2.push_back(i);
if (i >= k)
{
ans1.push_back(a[q1.front()]);
ans2.push_back(a[q2.front()]);
}
}
for (int i = 0; i <= n - k; i++)
pr("%d%c", ans1[i], i == n - k ? '\n' : ' ');
for (int i = 0; i <= n - k; i++)
pr("%d%c", ans2[i], i == n - k ? '\n' : ' ');
} 
京公网安备 11010502036488号