单调队列就是队列中的元素是单调递增或递减的。比如把 5 2 3 1 4 入队:
减:、、、、、、、、、、、增:
5 、、、、、、、、、、、、5
5 2 、、、、、、、、、、、2
5 3 、、、、、、、、、、、2 3
5 3 1、、、、、、、、 、、1
5 4 、、、、、、、、、、、1 4
 
这个还是好理解的,但是,我们得会用单调队列这一特性去解决题目,抽象出题目中有类似的操作。
题意:
给三个数   n,x,y;
 
接下来n个数num[1~n];
求满足这个条件的最长区间长度:区间内最大值与最小值之差在 x~y之间。
方法:
单调队列记录下标。
由一个递增,一个递减的单调队列,可得前面的某个位置~当前位置的最大差值def=num[q1.front()]-num[q2.front()];
如果def>y,则让下标靠前的那个出队列。
 
上代码,看注释:
#include <stdio.h>
#include <iostream>
#include <deque>
using namespace std;
inline int  fmax(int a,int b){return a>b?a:b;}  
int main()
{
    int n,x,y;
    int num[100005];
    while(scanf("%d %d %d",&n,&x,&y)!=EOF)
    {
        for(int i=1;i<=n;++i)
            scanf("%d",&num[i]);
        deque<int >q1,q2;   //两个队列,q1.front()存最大值,q2.front()存最小值
        int max=0,last=0;   //last记录最后弹出元素的位置
        for(int i=1;i<=n;i++){
            while(!q1.empty() && num[i]>num[q1.back()]) q1.pop_back();//维护队列单调型
            while(!q2.empty() && num[i]<num[q2.back()]) q2.pop_back();
            q1.push_back(i);
            q2.push_back(i);
        //若对不空,且def>y,让下标靠前的出队。
            while(!q1.empty() && !q2.empty() && num[q1.front()]-num[q2.front()]>y){
                if(q1.front()>q2.front())
                {
                    last=q2.front();
                    q2.pop_front();
                }
                else if(q1.front()<q2.front())
                {
                    last=q1.front();
                    q1.pop_front();
                }
                else if(q1.front()>q2.front())
                {
                    last=q2.front();
                    q1.pop_front();
                    q2.pop_front();
                }
            }
        
            if(!q1.empty() && !q1.empty() && num[q1.front()]-num[q2.front()]>=x)
                max=fmax(max,i-last);//若当前区间的def满足>=x,取区间最大长度
        }
        printf("%d\n",max);
    }
    return 0;
}
 
 
 
 
                   
                   
                   
                   
                             本文介绍使用单调队列解决区间最大最小值差问题的方法。通过维护递增递减两个队列,动态调整区间,实现高效查找。适用于编程竞赛及算法优化场景。
本文介绍使用单调队列解决区间最大最小值差问题的方法。通过维护递增递减两个队列,动态调整区间,实现高效查找。适用于编程竞赛及算法优化场景。
           
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   649
					649
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            