在做此题时,先是求了,最大值,当窗口中,最右边的数,比窗口内左边的数大的时候,那么左边的数就不可能成为此窗口中,最大的数,因此在此题中,用了两个双端队列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; }