T61:滑动窗口最大值(Java)

题目:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

分析:先构建一个LinkedList队列 ,用于存放数组下标!!!for 循环以{2,3,4,2,6,2,5,1}及滑动窗口的大小3为例

i=0   num[0]=2      2 入列

i=1   num[1]=3 3>队尾,删除队尾   3入列

i=2  num[2]=4  4>队尾 ,删除队尾  4入列   最大值4  从此时可以记录最大值即队首元素可见上述操作只是为了保持队首元素最大

i=3  num[3]=2  2<队尾 ,2 入列   此时 队内有  4\rightarrow2 最大值依旧为队首元素4

i=4 num[4]=6   6>队尾  删除2 6>队尾4 删除  此时队内空 终止循环 6入队 最大值队首元素6

i=5 num[5]=2   2<队尾  2入队   此时栈内6\rightarrow2 最大值队首元素6

i=6 num[6]=5   5>队尾  删除2  此时栈内 6\rightarrow5  最大值队首元素6

i=7 num[7]=1  1<队尾  1入队 此时栈内6\rightarrow5\rightarrow1??错,这时6已过期 判断条件为 i>=queue.peek(4)+size(3)。pop队首 这样最大值为5.

循环结束

 

注意 linkedlist 的removelast()方法是移除队尾 addlast是在队尾增加元素 pop是弹出队首并删除 peek是只是弹出队首。

 

 


import java.util.ArrayList;
import java.util.LinkedList;
/*
 * 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。
 * 例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,
 * 他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: 
 * {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1},
 *  {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
 */
public class maxInWindows1 {
	public static ArrayList<Integer> maxInWindows(int [] num, int size)
    {   
		ArrayList<Integer>  result=new ArrayList<Integer>();
		if(num.length==0||size==0||size>num.length||num==null){
			return result;
		}
		//思考此处为何要用LinkedList  存放的是数组的下标
		LinkedList<Integer> queue=new LinkedList<Integer>();
		for(int i=0;i<num.length;i++){
			if(!queue.isEmpty()){
			if(i>=queue.peek()+size){
				queue.pop();
			}
			while(!queue.isEmpty()&&num[i]>num[queue.getLast()]){//当前数与队尾比较
				queue.removeLast();
			}
			}
			queue.add(i);
			if(i+1>=size){
				result.add(num[queue.peek()]);//peek是取出但是不删除
			}
		}
		return result;
		
        
    }
	public static void main(String[] args) {
		int [] num={2,3,4,2,6,2,5,1};
		int size=3;
		
		System.out.println(maxInWindows(num,size));
	}
}

 

 

 

 

 

 

参考:https://blog.csdn.net/u010429424/article/details/73692248

        queue:https://www.cnblogs.com/lemon-flm/p/7877898.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值