标签:color new blog algo res term second ram mat
Sliding Window
Description
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.
Input
Output
Sample Input
8 3
1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3 3 3 5 5 6 7
題意 :
给定一个数字序列,与每次所能看见的序列长度m即窗户长度,从左向右依次移动窗户,输出每次所能看到的序列长度的最大值与最小值,直到序列结束.
思路:
以求最小值为例,
1.构造递增的单调队列,即队尾元素需要小于当前元素,否则队尾元素出队.
2.首先,将前 m-1 个元素按照单调队列原则进队,并记录队列中的每个元素在数组中的下标;
其次,将剩余的元素依次进队,以 第i元素为例子,将第i元素与队尾比较,若是小于队尾,则队尾出队,否则当前元素进队,此时队列是单调递增有序的,
再之,将队头元素的下标与当前元素的下标比较,若 当前元素下标 - 队头元素下标<=m-1,则队头元素便为最小值,否则队头出队.
3.将剩余元素依次进行步骤2,便得到所求的所有最小值,求最大值亦然.
AC代码分析 (请用C++提交,否则Time Limit Exceeded):
1 #include <iostream> 2 #include <stdio.h> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <vector> 7 #include <map> 8 #include<string.h> 9 #include<stack> 10 #include<set> 11 #include <queue> 12 using namespace std; 13 int a[1000005]; 14 //队列中各元素的下标 15 int p[1000005]; 16 //各个区间的最大值 17 int max1[1000005]; 18 //各个区间的最小值 19 int min1[1000005]; 20 //数组模拟递增队列 21 int qmax[1000005]; 22 //数组模拟递减队列 23 int qmin[1000005]; 24 //队头,队尾 25 int head,tail; 26 int main() 27 { 28 int n,m,i,t; 29 while(~scanf("%d%d",&n,&m)) 30 { 31 for( i = 1; i<=n; i++) scanf("%d",a+i); 32 //队头队尾初始化 33 head = 1; 34 tail = 0; 35 t = 1; 36 //前m-1个元素进队列 37 for( i = 1; i<=m-1; i++) 38 { 39 while(head<=tail&&qmin[tail]>=a[i]) tail--; 40 qmin[++tail] = a[i]; 41 //队列中各元素的下标 42 p[tail] = i; 43 44 } 45 //求所有的最小值 46 for(; i<=n; i++) 47 { 48 //进队 49 while(head<=tail&&qmin[tail]>=a[i]) tail--; 50 qmin[++tail] = a[i]; 51 p[tail] = i; 52 //判断对头是否在当前范围内 53 while(i-p[head]>m-1) 54 head++; 55 min1[t++] = qmin[head]; 56 } 57 head = 1; 58 tail = 0; 59 t = 1; 60 //求所有的最大值 61 for( i = 1; i<=m-1; i++) 62 { 63 while(head<=tail&&qmax[tail]<=a[i]) tail--; 64 qmax[++tail] = a[i]; 65 p[tail] = i; 66 } 67 for(; i<=n; i++) 68 { 69 //进队 70 while(head<=tail&&qmax[tail]<=a[i]) tail--; 71 qmax[++tail] = a[i]; 72 p[tail] = i; 73 //判断对头是否在当前范围内 74 while(i-p[head]>m-1) 75 head++; 76 max1[t++] = qmax[head]; 77 } 78 for( i = 1; i<t; i++) 79 { 80 if(i == 1) 81 printf("%d",min1[i]); 82 else 83 printf(" %d",min1[i]); 84 } 85 printf("\n"); 86 for( i = 1; i<t; i++) 87 { 88 if(i == 1) 89 printf("%d",max1[i]); 90 else 91 printf(" %d",max1[i]); 92 } 93 94 } 95 return 0; 96 }
本文为个人随笔,如有不当之处,望各位大佬多多指教.
若能为各位博友提供小小帮助,不胜荣幸.
POJ--2823--Sliding Window----单调队列问题
标签:color new blog algo res term second ram mat
原文地址:http://www.cnblogs.com/LGJC1314/p/6881854.html