Acwing 154 sliding window (monotone queue) classic template

Given a size of n- 10 . 6 array of n≤106.

There is a sliding window of size k, which moves from the leftmost to the rightmost array.

You can only see k numbers in the window.

Each sliding window moves to the right one position.

Here is an example:

The array is [1 3 -1 -3 5 3 6 7], k is 3.

 

Window position Minimum Maximum
[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 each sliding window position is located, in the window.

Input Format

Input contains two lines.

The first line contains two integers n and k, representing the length of the array and the length of the sliding window.

The second row has n integer representing the specific numerical values ​​of the array.

Data between peers separated by a space.

Output Format

The output contains two.

A first output line, from left to right, the minimum value of each position of the sliding window.

A second output line, from left to right, the maximum value of each position of the sliding window.

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

 

This problem we can use to solve an array of analog queues, each queue for maintenance, we traverse this number string from left to right, imagine a sliding window of length k continue to the right in the above ~

And (to a minimum, for example), every time we enter a team number in this window, if Ai> Aj && i <j, then we will never use Ai, Ai will be a team (ie pop Aj Aj is larger than all the previous number), then we obtained queue is a strictly monotonically increasing queue, each output can be the first team

I personally think that this code is the hardest to understand: when the window across, how to update the queue, it can be understood, the first item in the queue is always the position of the minimum window inside us, if we go through when i found a ratio the first item on the queue position of a smaller number, this number will be the location, updating the first entry into the queue, otherwise the team has been in the queue tail addend, and when I traversed to the current position i, i-k + 1 > q [hh], that is to say in the extreme case, q [hh] is the window left border, i is the right border of the window, we need to h ++ to maintain the queue.

 

Specific operation:

 1 3 -1 -3 5 3  6 7

The first step: The enqueue 1, hh = 0, q [0] = 0;

Step: 1 <3, the enqueue 3, hh = 0, q [0] = 0, q [1] = 1;

Step: 3> -1, the number of the foregoing are dequeued -1 is enqueued, hh = 0, q [0] = 2, the output of a [2] = - 1;

Step Four: -1> -3, the number of the foregoing are dequeued, the enqueue -3, hh = 0, q [0] = 3, the output of a [3] = - 3;

Step Five: -3 <5, 5 enqueue, hh = 0, q [0] = 3, q ​​[1] = 4, the output of a [3] = - 3;

Step Six: 5> 3, the five teams, the team 3, hh = 0, q [0] = 3, q ​​[1] = 5, the output of a [3] = - 3;

Seventh Step: 3 <6, 6 will enqueue, then i-k + 1 = 4, hh ++, hh = 1, q [1] = 5, q [2] = 6, the output of a [5] = 3 ;

Step eight: 6 <7, 7 will enqueue, hh = 1, hh = 1, q [1] = 5, q [2] = 6, 3 output;

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#define ll long long
const int N=1e6+10;
using namespace std;
typedef pair<int,int>PII;

int n,k;
int a[N],q[N];

int main(){
 ios::sync_with_stdio(false);
 cin>>n>>k;
 for(int i=0;i<n;i++)  cin>>a[i];
 int hh=0,tt=-1;
for(int i=0;i<n;i++){
  //判断队头是否已经划出窗口
  if(hh<=tt && i-k+1>q[hh]) hh++;
   while(hh<=tt && a[q[tt]]>=a[i]) tt--;
   q[++tt]=i;
   if(i>=k-1)  cout<<a[q[hh]]<<' ';
}
  return 0;
}

 

Guess you like

Origin www.cnblogs.com/lr599909928/p/12325346.html