剑指offer面试题 ---- 滑动窗口的最大值

参考http://blog.sina.com.cn/s/blog_a1ce3d4b0102wkxg.html,给出自己的理解

 

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

思路就是:维护一个双端队列(双端队列保存的是数组的下标)。遍历给出数组(从size-1到length-1),对于每一个元素:

如果当前元素大于队列尾部,就从队列尾部删除元素,直到队列没有比当前元素小的元素(while循环)。

然后根据当前元素下标,判断队列头(按照上面的做法,队列head元素会是队列中最大的元素)是否在窗口有效范围内,如果不是就不断删除head元素直到合法。

package test;

import java.util.Scanner;

import java.util.*;

public class main {
	
	public static void main(String args[]) {
		int[] test = {2,3,4,2,6,2,5,1};
		int size = 3;
		System.out.println(maxInWindows(test,size));
	}

   public static ArrayList maxInWindows(int [] num, int size){

        ArrayList list=new ArrayList<>();

       if (num == null)

           return list;

       if (num.length < size || size < 1)

           return list;

       LinkedList indexDeque = new LinkedList<Integer>();

/*       
 * 		这一段是初始化双端队列用的,对于样例:2 3 4 2 6 2 5 1,之所以是size-1是因为窗口大小是3的话,
 * 		那么从第三个元素(下标是2)开始,就需要判断当前窗口最大值
 * 		第一次循环i=0,双端队列是空,执行indexDequeue.addLast(0);
 * 		第二次循环i=1,元素3大于元素2(队列尾部),while循环删除队列尾部,然后将当前元素添加,此时队列中只有3,
 * 		i=3 退出for循环,初始化完成,从这里也可以看出这道题的思路
*/
       for (int i = 0; i < size - 1; i++) {
		           while (!indexDeque.isEmpty() && num[i] >num[(int) indexDeque.getLast()]) {
		               indexDeque.removeLast();
		           }
		           indexDeque.addLast(i);
        }
        



       for (int i = size - 1; i < num.length; i++) {
    	   
    	   //while循环不断删除尾部元素
           while (!indexDeque.isEmpty() && num[i] >num[(int) indexDeque.getLast()]) {

               indexDeque.removeLast();

           }
           //然后将当前元素添加到尾部
           indexDeque.addLast(i);
           
           //如果头部元素超过范围
           if (i - (int)indexDeque.getFirst() + 1 > size) {

               indexDeque.removeFirst();

           }
           //取出队列头部元素放入结果集
           list.add(num[(int) indexDeque.getFirst()]);

        }

       return list;

    }

}

  

 

posted @ 2018-04-19 16:39  CoderLynn  阅读(174)  评论(0编辑  收藏  举报