题目
解题思路一暴力
用队列模拟窗口,在窗口中暴力搜索最小值/最大值,时间复杂度为O(n^2)
代码模板
#include<iostream>
using namespace std;
const int N=1e5+10;
int n,k,index,ne;
int q[N];
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++)
{
cin>>q[i];
}
for(index=0,ne=k-1;ne<n;index++,ne++)
{
int min=1e6;
for(int i=index;i<=ne;i++)
{
if(q[i]<min)min=q[i];
}
printf("%d ",min);
}
cout<<endl;
for(index=0,ne=k-1;ne<n;index++,ne++)
{
int max=-1e6;
for(int i=index;i<=ne;i++)
{
if(q[i]>max)max=q[i];
}
printf("%d ",max);
}
return 0;
}
解题思路一单调队列
找最小值:建立单调队列,并保持队列长度小于等于设定的K值,每次读入新值时,如果新值大于队尾值则再保证队列长度的情况下往队尾插值,如果新值小于队尾值,则队尾退至最小于新值的合法位置(地址大于等于队头)。
找最大值同理
代码实现注意点:在窗口容满时才开始输出,
r- -和r++书写为队列规范
初始值r=-1的原因首次写入时单调队列下标为0,统一规范
代码模板
#include<iostream>
using namespace std;
const int N=1e6;
int n,k,l,r,a[N],q[N];
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
l=0,r=-1;
for(int i=0;i<n;i++)
{
if(l<=r&&i-q[l]+1>k)l++;
while(l<=r&&a[i]<=a[q[r]])r--;
q[++r]=i;
if(i>=k-1)printf("%d ",a[q[l]]);
}
l=0,r=-1;
cout<<endl;
for(int i=0;i<n;i++)
{
if(l<=r&&i-q[l]+1>k)l++;
while(l<=r&&a[i]>=a[q[r]])r--;
q[++r]=i;
if(i>=k-1)printf("%d ",a[q[l]]);
}
return 0;
}