[Acwing]154. 滑动窗口 原创
算法标签 单调栈 滑动窗口
题目简叙

思路
模拟队列 利用单调队列的思路来控制
 队列放的是原本字符串的下标
查询最小值
 每次检查数值是否小于队尾元素,如果是,则循环删去队尾,直到新元素比前一个元素更大
 这样我们就营造了一个递增的单调序列,最小值永远是队头
 然后返回队头即可
代码
#include<iostream>
#include<vector>
using namespace std;
int n,k,tmp;
const int N=1e6+10;
int a[N];
int q[N];
int main(){
    cin>>n>>k;
    
    for(int i=0;i<n;i++)cin>>a[i];
    
    int st=0,ed=-1;
    for(int i=0;i<n;i++){
        if(st<=ed&&q[st]<i-k+1)st++;//如果当前队头元素太小了,不在K的范围区间,则删除对头
        while(st<=ed&&a[i]<a[q[ed]])ed--;//每次检查数值是否小于队尾元素,如果是,则循环删去队尾,直到新元素比前一个元素更大
        q[++ed]=i;//队尾添加新的下标
        if(i>=k-1)cout<<a[q[st]]<<" ";//如果扫描位置到了k-1,表明从现在开始需要反映出各个窗口的最小值
    }
    
    st=0,ed=-1;
    cout<<endl;
    for(int i=0;i<n;i++){
        if(st<=ed&&q[st]<i-k+1)st++;
        while(st<=ed&&a[q[ed]]<=a[i])ed--;
        q[++ed]=i;
        if(i>=k-1)cout<<a[q[st]]<<" ";
    }
    
    return 0;
}
AC记录

 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号