单调队列问题

单调队列是一种特殊的队列,可以在队头和队尾两边操作,并且始终维护队列的单调性。这种单调性分为两种:元素值严格单调, 元素下标严格单调

滑动窗口最大值

这是一道经典的单调队列问题,因为滑动窗口一直都是动态变化,并且要求出窗口中的最大值,那么我们可以通过建立单调递减的队列,队头即为最大值,那么我们在每次滑动窗口的时候,判断队头元素是否已经划出窗口来判断最大值是否合法,如果合法则为当前窗口的最大值,如果不合法那么队头出列,因此我们每次入队的是元素的下标。每当滑动窗口往前移动一个单位就是要新进来一个数字,那么我们要判断新进来的数字是否要替换队列中的元素,因为要维护单调递减的队列,那么如果新的数字要大于队尾就要让队尾的元素删除并且添加新进来的元素,以此来维护单调队列

public class 单调队列优化 {
	public static void main(String[] args) {
		Scanner sr = new Scanner(System.in);
		int m = sr.nextInt();//输入数组长度
		int f[] = new int[m+1];//目标数组
		for(int i=1;i<=m;++i){
			f[i] = sr.nextInt();
		}
		int k = sr.nextInt();//窗口长度
		int dl_down[] = new int[k+1];//减序队列数组,找最大值
		int Min[] = new int[m+1];
		int Max[] = new int[m+1];
		int st = 1,ed = 1;//定义队列的两个指针
		//初始化值
		dl_down[1] = 1;
		Min[1] = f[dl_down[1]];
		ed++;
		for(int i=2;i<=m;++i) {//遍历数组 
			while(st<ed) {//st==ed空队列,第i个数小于队尾就将队尾删除,ed--
				if(f[i] >= f[dl_down[ed-1]])ed--;
				else {
					break;
				}
			}
			dl_down[ed++] = i;//将i存入
			//更新min,判断对头是否过时
			if(dl_down[st]<i-k+1)st++;
			Min[i] = f[dl_down[st]];
		}
		for(int i=k;i<=m;++i) {
			System.out.print(Min[i]);
		}
	}	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值