zoukankan      html  css  js  c++  java
  • 剑指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;
    
        }
    
    }
    

      

  • 相关阅读:
    ASP.NET 设计模式 读书摘记1
    [Exception]Sys.WebForm.PageRequestManagerServerErrorException:500
    [Exception] 当前 TransactionScope 已完成
    [Javascript]客户端检测
    c.Tom and paper
    Currency System in Geraldion (Codeforces 560A)
    巡逻机器人(BFS)
    比赛建金字塔问题解题报告
    除法(暴力)
    比赛找丢失的数解题报告T
  • 原文地址:https://www.cnblogs.com/coderlynn/p/8884171.html
Copyright © 2011-2022 走看看