Sliding Window

Sliding Window
Question Description

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 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.

输入描述:
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.
输出描述:
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.
示例1
输入
复制
8 3
1 3 -1 -3 5 3 6 7
输出
复制
-1 -3 -3 -3 3 3
3 3 5 5 6 7

Idea: The question asks us to output the minimum value of the interval in an interval of length k each time. You can see at a glance that this question is a sliding window template question. We can use a double-ended queue to maintain this length. is the sliding window of k, and then we let this window move every time, and maintain the maximum or minimum value of the window during the movement (the maintained answer is at the head of the queue). The focus is how to maintain this queue.
First, when this window is going to slide backwards, we need to delete the head of the queue:

if(!q1.empty()&&q.front()+k-1<i)//队列不空且队列右端点小于i(i是从0开始的)的值
	q1.pop_front();

So how do we maintain the minimum value of the window header? When our tail is larger than the element that is coming in, we need to delete the tail element. The purpose of this is to let the minimum value in the window go to the head of the window:

while(!q1.empty()&&a[i]<a[q1.back()])//当队列不空且当前值小于队尾值
	q1.pop_back();

Finally, when the window we maintain reaches k, the data is output.
Accode:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>

using namespace std;

const int N = 1e6+5;
int a[N];

void minx(int n,int k)
{
    
    
    deque<int>q1;
    for(int i=0;i<n;i++)
    {
    
    
        while(!q1.empty()&&a[i]<a[q1.back()])
            q1.pop_back();
        if(!q1.empty()&&q1.front()+k-1<i)//更新窗口区间的最小值
            q1.pop_front();
        q1.push_back(i);//将下标入队
        if(i+1>=k)cout<<a[q1.front()]<<' ';
    }
}

void maxx(int n,int k)
{
    
    
    deque<int>q2;
    for(int i=0;i<n;i++)
    {
    
    
        while(!q2.empty()&&a[i]>a[q2.back()])
            q2.pop_back();
        if(!q2.empty()&&q2.front()+k-1<i)//更新窗口区间的最大值
            q2.pop_front();
        q2.push_back(i);
        if(i+1>=k)cout<<a[q2.front()]<<' ';
    }

}

int main()
{
    
    
    int n,k;
    cin>>n>>k;
    for(int i=0;i<n;i++)cin>>a[i];
    minx(n,k);
    cout<<endl;
    maxx(n,k);
    return 0;
}

Guess you like

Origin blog.csdn.net/Stephen_Curry___/article/details/126733611