POJ 2823 -- Sliding Window


2823 -- Sliding Window
An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example:
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
Window positionMinimum valueMaximum value
[1  3  -1] -3  5  3  6  7 -13
 1 [3  -1  -3] 5  3  6  7 -33
 1  3 [-1  -3  5] 3  6  7 -35
 1  3  -1 [-3  5  3] 6  7 -35
 1  3  -1  -3 [5  3  6] 7 36
 1  3  -1  -3  5 [3  6  7]37
Your task is to determine the maximum and minimum values in the sliding window at each position.
Input
The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.
Output
There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.
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
http://www.cnblogs.com/zhexipinnong/archive/2012/05/01/2477852.html
单调队列,顾名思义,就是一个元素单调的队列,那么就能保证队首的元素是最小(最大)的,从而满足动态规划的最优性问题的需求。
一般,在动态规划的过程中,单调队列中每个元素一般存储的是两个值:
1.      在原数列中的位置(下标)
2.      他在动态规划中的状态值
而单调队列则保证这两个值同时单调。
 从以上看,单调队列的元素最好用一个类来放,不这样的话,就要开两个数组。。。
 插入方法(以最大单调队列为例):
在插入一个元素前,先判断队列是否为空(head<=tail),然后再判断队尾元素是否比要插入的元素小(q[tail].val<data[insert]),如果是的话,则将队尾元素删除(--tail)。
重复以上过程,直至为空或队尾元素比其大。
删除方法:
    这个要根据具体题目而定。在本题是如果当前的INDEX与队首的INDEX相差大于等于K,则删除。
 3 int a[MAXN],bque[MAXN],sque[MAXN];
 4 int n,k;
 5 void getmax()
 6 {
 7     int i,head = 1,tail = 1;
 8     for(i = 1;i < k;i++)
 9     {
10         while(tail >= head && a[i] > a[bque[tail]])//队列不为空且当前元素大于队尾元素
11             tail--;//删除队尾元素
12         tail++;
13         bque[tail] = i;
14     }
15     for(i = k;i <= n;i++)
16     {
17         while(tail >= head && i - bque[head] >= k)//队列不为空,且当前元素下标减去队首元素的下标>=k
18             head++;//删除队首元素
19         while(tail >= head && a[i] > a[bque[tail]])//队列不为空且当前元素大于队尾元素
20             tail--;
21         tail++;
22         bque[tail] = i;
23         if(i != n)
24             printf("%d ",a[bque[head]]);
25     }
26     printf("%d\n",a[bque[head]]);
27 }
28 void getmin()
29 {
30     int i,head = 1,tail = 1;
31     for(i = 1;i < k;i++)
32     {
33         while(tail >= head && a[i] < a[sque[tail]])
34             tail--;
35         tail++;
36         sque[tail] = i;
37     }
38     for(i = k;i <= n;i++)
39     {
40         while(tail >= head && i - sque[head] >= k)
41             head++;
42         while(tail >= head && a[i] < a[sque[tail]])
43             tail--;
44         tail++;
45         sque[tail] = i;
46         if(i != n)
47             printf("%d ",a[sque[head]]);
48     }
49     printf("%d\n",a[sque[head]]);
50 }
51 int main()
52 {
53     while(~scanf("%d%d",&n,&k))
54     {
55         for(int i = 1;i <= n;i++)
56             scanf("%d",&a[i]);
57         getmin();
58         getmax();
59     }
60     return 0;
61 }
http://www.programerhome.com/?p=29776
int qmin[maxn], vmin[maxn], hmin = 1, tmin = 0; 
void Min(int a, int i) {  //第i个元素a入队 
 while(hmin<=tmin && vmin[hmin] <= i-k) hmin++;  //超范围队首出队 
 //while(hmin<=tmin && qmin[tmin]>=a) tmin--; //不符合要求队尾出列 
 int l = hmin, r = tmin;
 while(l <= r) {
  int m = l+(r-l)/2;
  if(qmin[m] >= a) r = m - 1;
  else l = m + 1; 
 }
 tmin = ++r;
 qmin[tmin] = a;
 vmin[tmin] = i;
}
int qmax[maxn], vmax[maxn], hmax = 1, tmax = 0; 
void Max(int a, int i) {  //第i个元素a入队 
 while(hmax<=tmax && vmax[hmax] <= i-k) hmax++;  //超范围队首出队 
 //while(hmax<=tmax && qmax[tmax]<=a) tmax--; //不符合要求队尾出列 
 int l = hmax, r = tmax;
 while(l <= r) {
  int m = l+(r-l)/2;
  if(qmax[m] <= a) r = m - 1;
  else l = m + 1; 
 }
 tmax = ++r;
 qmax[tmax] = a;
 vmax[tmax] = i;
}
int ansMax[maxn], ansMin[maxn];
int main() {
 while(scanf("%d%d", &n, &k) == 2) {
  hmin = 1, tmin = 0;
  hmax = 1, tmax = 0;
  for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
  for(int i = 1; i < k; i++) {
   Min(a[i], i);
   Max(a[i], i);
  }
  for(int i = k; i <= n; i++) {
   Min(a[i], i);
   ansMin[i-k] = qmin[hmin];
   Max(a[i], i);
   ansMax[i-k] = qmax[hmax];
  }
  for(int i = 0; i <= n-k; i++) 
   if(i != n-k) printf("%d ", ansMin[i]);
   else printf("%d/n", ansMin[i]);
  for(int i = 0; i <= n-k; i++) 
   if(i != n-k) printf("%d ", ansMax[i]);
   else printf("%d/n", ansMax[i]);
 }
 return 0;
}
http://blog.csdn.net/kenden23/article/details/37598147
本题是单调队列题解的入门,当然也可以使用RMQ 和 线段树,不过速度都没有单调队列那么快。
单调队列难点:
1 如何入列,保存数据 -- 最小单调队列的时候, 所有数都入列一次,在新的数据准备入列的时候,增加判断,如果当前数值小于队尾数值,那么队尾数值就出列。空队列的时候直接入列。
  1. void getMins()  
  2. {  
  3.     int tail = 0, head = 1; //初始化tail<head表示为空列  
  4.     for (int i = 1; i < K; i++)  //初始化单调队列  
  5.     {  
  6.         while (tail >= head && qu[tail] >= arr[i]) tail--;  
  7.         qu[++tail] = arr[i];        //记录可能的答案值  
  8.         index[tail] = i;    //记录额外需要判断的信息  
  9.     }  
  10.     for (int i = K; i <= N; i++)  
  11.     {  
  12.         while (tail >= head && qu[tail] >= arr[i]) tail--; //不符合条件出列  
  13.         qu[++tail] = arr[i];  
  14.         index[tail] = i;  
  15.         while (index[head] <= i-K) head++;  
  16.         ans[i-K] = qu[head];    //ans从下标0开始记录  
  17.     }  
  18. }  
  19.   
  20. void getMaxs()  
  21. {  
  22.     int tail = 0, head = 1;  
  23.     for (int i = 1; i < K; i++)  //初始化单调队列  
  24.     {  
  25.         while (tail >= head && qu[tail] <= arr[i]) tail--;  
  26.         qu[++tail] = arr[i];  
  27.         index[tail] = i;  
  28.     }  
  29.     for (int i = K; i <= N; i++)  
  30.     {  
  31.         while (tail >= head && qu[tail] <= arr[i]) tail--; //不符合条件出列  
  32.         qu[++tail] = arr[i];  
  33.         index[tail] = i;  
  34.         while (index[head] <= i-K) head++;  
  35.         ans[i-K] = qu[head];    //ans从下标0开始记录  
  36.     }  
  37. }  
https://blog.csdn.net/acvay/article/details/46772771
  const int N = 1e6 + 5;
  int a[N], q[N], t[N];
  int front, rear, n, k;
   
  #define NOTMONO (!op && a[i] < q[rear - 1]) || (op && a[i] > q[rear - 1])
  void getMonoQueue(int op) //op = 0 时单增队列  op = 1 时单减队列
  {
      front = rear = 0;
      for(int i = 0; i < n; ++i)
      {
          while( rear > front && (NOTMONO)) --rear;
          t[rear] = i;      //记录滑窗滑到i点的时间
          q[rear++] = a[i];
          while(t[front] <= i - k) ++front;  //保证队首元素在滑窗之内
          if(i > k - 2)
              printf("%d%c", q[front], i == n - 1 ? '\n' : ' ');
      }
  }
   
  int main()
  {
      while (~scanf("%d%d", &n, &k))
      {
          for(int i = 0; i < n; ++i)
              scanf("%d", &a[i]);
          getMonoQueue(0); //单增队列维护最小值
          getMonoQueue(1); //单减队列维护最大值
      }
   
      return 0;

  }
https://www.programering.com/a/MDMzITMwATg.html
Read full article from 2823 -- Sliding Window

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts