提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
题目链接
154.滑动窗口
思路
利用单调队列维护数组下标,以维护最小值举例
维护队列的单调递增性(保持对头最小)
当一个数的后一个数比前一个数大
也就是如果队列中存在两个元素,满足 a[i] >= a[j] 且 i < j,那么无论在什么时候我们都不会取 a[i] 作为最小值了,所以可以直接将 a[i] 删掉
在这个基础上加入一个 如果当前遍历的数下标大于队头的下标k - 1,则删除该队头(因为滑动窗口已经过了当前位置)
代码如下:
#include<iostream>
using namespace std;
#define MAX 1000010
int num[MAX], q[MAX];
int main()
{
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i++)
{
cin >> num[i];
}
int min_h = 0, min_l = -1;
for (int i = 0; i < n; i++)
{
if (min_h <= min_l && q[min_h] + k - 1 < i) min_h++;
while (min_h <= min_l && num[q[min_l]] >= num[i]) min_l--;
q[++min_l] = i;
if (i >= k - 1) cout << num[q[min_h]] << " ";
}
cout << endl;
min_h = 0;
min_l = -1;
for (int i = 0; i < n; i++)
{
if (min_h <= min_l && q[min_h] + k - 1 < i) min_h++;
while (min_h <= min_l && num[q[min_l]] <= num[i]) min_l--;
q[++min_l] = i;
if (i >= k - 1) cout << num[q[min_h]] << " ";
}
return 0;
}