题目链接:

题意:

给 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' : ' ');
}