滑动窗口

滑动窗口算法

2019-02-26  本文已影响0人  Never_68dd

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。

思想:构建一个双端队列,begin为窗口左边界,队头为当前窗口的最大数值,每次滑动一次,则把新加的数值加入队尾并进行比较,如果大于前一个数,则弹出,则到队列为空或者数值比当前数值小,并且,每次获取队列时,应该比较当前的begin与队列头的数值的位置,查看队列数值是否过期,保证数值在当前的窗口里面。

画图分析

一开始时,begin应从-2开始(判断条件为begin大于等于0时开始获取最大值,这样可以保证第一次窗口有3个数值),此时窗口内有一个值为2,把下标写入队列;

​     

begin 右滑动,此时滑动窗口进入新的数字,从队尾开始比较,3比2大,则把 队列中的下标0弹出,此时队列为空,把3的下标1压入,此时判断begin与queue.peek()大小,可知没有过期,但是由于begin小于0,不做弹出操作

窗口滑动,此时按照步骤,弹出3的下标1,并把4的下标2压入队尾,此时 2>begin,所以没有过期,且begin=0,从此时开始,开始了获取最大值的操作,获取队头,则为当前最大值

按照这个步骤,逐步求值

代码

//num 为输入的数组  size 为滑动窗口大小

publicArrayList<Integer>maxInWindows(int[]num,intsize)

   {

ArrayList<Integer>list=newArrayList<Integer>();

if(size==0)returnlist;

ArrayDeque<Integer>queue=newArrayDeque<>();

intbegin;

for(inti=0;i<num.length;i++){

begin=i-size+1;//从-2开始![微信图片_20190226103532](C:\Users\ASUS\Desktop\新建文件夹\微信图片_20190226103532.png)

if(queue.isEmpty()){

queue.add(i);

       }

elseif(begin>queue.peekFirst()){//判断下标是否过期

    queue.pollFirst();

       }

while(!queue.isEmpty()&&num[queue.peekLast()]<=num[i]){//判断当前值的大小情况

queue.pollLast();

       }

queue.add(i);

if(begin>=0){

list.add(num[queue.peekFirst()]);

       }

     }

returnlist;

   }

}

上一篇下一篇

猜你喜欢

热点阅读