先用暴力:
for从k-1(大于板长)点循环
for 上级点往前找最小
分析:
如果i < j,a[ i ] > a[ j ],那么a[ i ]就一定不会用上,
即:前点>后点,那么前点就一定用不上 ,因为:后点的存在时间比前点长 && 不满足后点就一定不满足前点,所以构造递增序列即可
由题意,1.每次返回窗口内最小的值,所以是窗口(队列)内队头值 2.窗口有长度,所以使用队列控制长度
#include <iostream>
using namespace std;
const int N=1000005;
int n,k,q[N],a[N];
int hh,tt;
int main() {
cin>>n>>k;
hh=0, tt=-1;
//因为有长度限制所以是队列
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(q[hh]+k-1<i) hh++;//头+板长<尾(现点) ,队头的点已经在窗口外
while(hh<=tt&&a[q[tt]]>=a[i]) tt--;//队列不空且要加的点小于队尾(构建递增数组),
q[++tt]=i;//满足递增后压入
if(i>=k-1)printf("%d ",a[q[hh]]);//现点>板长+0(起始)窗口完全在数组内,防止之前部分窗口不在数组
}
printf("\n");
hh=0, tt=-1;//不要忘记初始化
for(int i=0;i<n;i++){
if(q[hh]+k-1<i) hh++;
while(hh<=tt&&a[q[tt]]<=a[i]) tt--;//改成<
q[++tt]=i;
if(i>=k-1)printf("%d ",a[q[hh]]);
}
printf("\n");
return 0;
} 
京公网安备 11010502036488号