题目
给定一个大小为n≤106的数组。
有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。
您只能在窗口中看到k个数字。
每次滑动窗口向右移动一个位置。
以下是一个例子:
该数组为[1 3 -1 -3 5 3 6 7],k为3。
输出格式
输出包含两个。
第一行输出,从左至右,每个位置滑动窗口中的最小值。
第二行输出,从左
至右,每个位置滑动窗口中的最大值。
输入样例
8 3
1 3 -1 -3 5 3 6 7
输出样例
-1 -3 -3 -3 3 3
3 3 5 5 6 7
C++
//数组模拟单调队列
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int a[N],q[N];
int n,k;
int main()
{
scanf("%d%d", &n,&k);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int t=-1,h=0;
for(int i= 0;i<n;i++)
{
if(h<=t&&i-k+1>q[h]) h++;//当队列长度大于k时 弹出队首
while(h<=t&&a[q[t]]>=a[i]) t--; //让队首的值最小
q[++t] = i;
if(i>=k-1) printf("%d ",a[q[h]]);
}
printf("\n");
t=-1,h=0;
for(int i=0;i<n;i++)
{
if(h<=t&&i-k+1>q[h]) h++; //当队列长度大于k时 弹出队首
while(h<=t&&a[q[t]]<=a[i]) t--;
q[++t] = i;
if(i>=k-1) printf("%d ",a[q[h]]);
}
return 0;
}
暴力超时了。。。
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int a[N],q[N];
int n,k;
int main()
{
scanf("%d%d", &n,&k);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=k-1;i<n;i++)
{
int min=a[i+1-k];
for(int j=i+1-k;j<=i;j++)
{
if(min>a[j])
min=a[j];
}
printf("%d ", min);
}
puts("");
for(int i=k-1;i<n;i++)
{
int max=a[i+1-k];
for(int j=i+1-k;j<=i;j++)
{
if(max<a[j])
max=a[j];
}
printf("%d ", max);
}
return 0;
}