在做此题时,先是求了,最大值,当窗口中,最右边的数,比窗口内左边的数大的时候,那么左边的数就不可能成为此窗口中,最大的数,因此在此题中,用了两个双端队列deque,一个用来记录最大值,另一个用来记录最小值,在求解最大值的时候,用maxn这个双端队列,记录的是输入数字的下标,第一if语句的判断,i-maxn.front()指的是当前数组中数字的下标i减去队列中,队头的下标是否大于等于滑动窗口的大小。如果满足那么就将队列前的元素弹出。接下来的while循环语句是如果队列不为空,并且当前的数字大于之前的数字那么,就将之前的数字弹出队列,因为,当前的数字比队列中前面的数字大并且在满足滑动窗口的大小,那么之前的数字就不可能成为最大值,故将其弹出。最后只输出以队头为下标的元素。
#include<iostream>
#include<deque>
using namespace std;
deque<int>maxn,minn;
long long n,k,a[1000010];
int main()
{
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for(int i=1;i<=n;i++)
{
if(!minn.empty()&&(i-minn.front()>=k))
{
minn.pop_front();
}
while(!minn.empty()&&(a[i] <= a[minn.back()]))
{
minn.pop_back();
}
minn.push_back(i);
if(i>=k)printf("%lld ",a[minn.front()]);
}
cout<<endl;
for(int i=1;i<=n;i++)
{
if(!maxn.empty()&&(i-maxn.front()>=k))
{
maxn.pop_front();
}
while(!maxn.empty()&&(a[i]>=a[maxn.back()]))
{
maxn.pop_back();
}
maxn.push_back(i);
if(i>=k)printf("%lld ",a[maxn.front()]);
}
return 0;
}

京公网安备 11010502036488号