生成窗口最大值数组 双端队列典型问题

本文介绍了一种利用双端队列求解滑动窗口最大值的问题,通过维护一个从大到小排列的元素下标队列,实现高效地获取每个窗口的最大值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:有一个整形数组arr和一个大小为window的窗口从数组的最左边滑到最右边,窗口每次向右边,窗口每次向右边滑一个位置。例如,数组为[4,3,5,4,3,3,6,7],窗口大小window=3时;

1)    [4 3 5] 4 3 3 6 7  窗口最大值为5

2)    4 [3 5 4] 3 3 6 7  窗口最大值为5

3)    4 3 [5 4 3] 3 6 7  窗口最大值为5

4)    4 3 5 [4 3 3] 6 7  窗口最大值为4

5)    4 3 5 4 [3 3 6] 7  窗口最大值为6

6)    4 3 5 4 3 [3 6 7]  窗口最大值为7

请将窗口的最大值按顺序输出。


该题使用双端队列解决,队列中始终维持着从大到小的数所在的下标。处理下一个数字的时候,比当前数字小的所有下标都从队列尾弹出去,因为这些数字不可能成为窗口的最大的数了。头部失效的弹出去


该题目使用的双端队列是这样一种队列:队头部可以弹出(头部失效的时候);队尾部可以弹出(当前情况下存储这个值没有意义,它不可能是我们感兴趣的输出),队尾也可以插入(当前值插入队尾)


package niuke07;

import java.util.LinkedList;

public class DoublePointQueue {
	public static int []a = {4,3,5,4,3,3,6,7};
	public static int window = 3;//窗口大小
	public static void main(String[] args) {
		doublePoint();
	}
	public static void doublePoint(){
		if(a==null ||a.length -window<0 ){
			return;
		}
		int []res = new int[a.length - window+1];//保存按顺序输出的结果
		int index = 0;
		LinkedList<Integer> list = new LinkedList<Integer>();
		for(int i=0;i<a.length;i++){
			while(!list.isEmpty() && a[list.peekLast()] < a[i]){
				list.pollLast();//比当前数字小的所有下标都弹出去
			}
			list.addLast(i);//当前数字下标插入队尾
			if(i - list.peekFirst() >= window){
				list.pollFirst();//头部失效,弹出去
			}
			if(i >= window-1){
				res[index++] = a[list.peekFirst()];//这时候的头部下标对应的数字就是最大值,保存下来
			}
		}
		for(int i=0;i<res.length;i++){
			System.out.print(res[i]+" ");
		}
		System.out.println();
	}
	

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值