Sliding window (monotonic queue)————AcWing

Title link
https://www.acwing.com/problem/content/description/156/
idea of
      a monotone queue simulation, for a given sequence s, a length of n, given a continuous length k, the seek [1,k],[2,k+1]...[n-k+1,n] The maximum or minimum value of these intervals. (The following explanation uses the minimum value) The
      most violent approach is naturally the double for loop

for(int i=0;i<n-k+1;i++)
{
    
    
    int MIN=1e9;
    for(int j=i;j<i+k;j++)
    {
    
    
        MIN=min(a[j],MIN);
    }
    cout<<MIN<<' ';
}

Obviously, the time complexity is O(n*k) level.

      So how to optimize it? We use the monotonic queue data structure to optimize. The idea is that some elements in the queue will not be selected as the minimum value, for example, for a given sequence (k=3)

1 3 -1 -3 5 3 6 7

For one of the windows (3 -1 -3), -3 is not only the minimum value inside, but also the survival time is longer than the two on the left, so 3 and -1 can be directly popped from the end of the queue. The following is the code for this question (the two-way queue in the code stores the subscript, not the value in the sequence.)

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6+5;

int n,m;
int a[N];

int main()
{
    
    
    scanf("%d%d",&n,&m);
    
    for(int i=0;i<n;i++)
    {
    
    
        scanf("%d",&a[i]);
    }
    
    deque<int> q1;
    for(int i=0;i<n;i++)
    {
    
    
        if(q1.size()&&q1.front()+m-1<i)
        {
    
    
            q1.pop_front();
        }
        while(q1.size()&&a[q1.back()]>=a[i])
        {
    
    
            q1.pop_back();
        }
        q1.push_back(i);
        if(i>=m-1)
        {
    
    
            printf("%d ",a[q1.front()]);
        }
    }
    puts("");
    deque<int> q2;
    for(int i=0;i<n;i++)
    {
    
    
        if(q2.size()&&q2.front()+m-1<i)
        {
    
    
            q2.pop_front();
        }
        while(q2.size()&&a[q2.back()]<=a[i])
        {
    
    
            q2.pop_back();
        }
        q2.push_back(i);
        if(i>=m-1)
        {
    
    
            printf("%d ",a[q2.front()]);
        }
    }
    puts("");
    return 0;
}

Guess you like

Origin blog.csdn.net/Star_Platinum14/article/details/112910589