标签:spec .com std strong cond algorithm style bsp fir
Window position | Minimum value | Maximum value |
---|---|---|
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
8 3 1 3 -1 -3 5 3 6 7
-1 -3 -3 -3 3 3 3 3 5 5 6 7
解题思路:这题不止一种做法,初学单调队列,这题作为入门题再适合不过了。单调队列维护固定区间长度的最值,求区间长为k中的最大值用单调递减队列,求区间长为k中的最小值用单调递增队列。单调队列和单调栈十分相似,但又有区别。相关讲解:单调队列总结。时间复杂度是O(n)。还有一点这道题要用C++提交,用G++会超时,原因不清楚=_=||。
AC代码(6829ms):
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<string.h> 5 #include<deque> 6 using namespace std; 7 const int maxn=1e6+5; 8 int n,k,a[maxn],minv[maxn],maxv[maxn]; 9 deque<int> dq1,dq2; 10 int main(){ 11 while(~scanf("%d%d",&n,&k)){ 12 for(int i=0;i<n;++i)scanf("%d",&a[i]); 13 dq1.clear();dq2.clear();memset(minv,0,sizeof(minv));memset(maxv,0,sizeof(maxv)); 14 for(int i=0;i<n;++i){ 15 while(!dq1.empty()&&a[dq1.back()]>=a[i])dq1.pop_back();//维护窗口最小值,单调递增队列 16 while(!dq2.empty()&&a[dq2.back()]<=a[i])dq2.pop_back();//维护窗口最大值,单调递减队列 17 dq1.push_back(i);dq2.push_back(i); 18 if(i-k+1>=0){//至少从第k个数开始才有区间最值 19 minv[i-k+1]=a[dq1.front()],maxv[i-k+1]=a[dq2.front()];//直接取队首在当前窗口的最值 20 if(dq1.front()==i-k+1)dq1.pop_front();//如果队首下标已经是最大区间(一共k个元素)的左端点值,则将其弹出,窗口向右移动 21 if(dq2.front()==i-k+1)dq2.pop_front(); 22 } 23 } 24 for(int i=0;i<=n-k;++i)//输出n-k+1个窗口中的最值 25 printf("%d%c",minv[i],i==n-k?‘\n‘:‘ ‘); 26 for(int i=0;i<=n-k;++i) 27 printf("%d%c",maxv[i],i==n-k?‘\n‘:‘ ‘); 28 } 29 return 0; 30 }
题解报告:poj 2823 Sliding Window(单调队列)
标签:spec .com std strong cond algorithm style bsp fir
原文地址:https://www.cnblogs.com/acgoto/p/9536419.html