【Java】 劍指offer(59-1) 滑動窗口的最大值

 

本文參考自《劍指offer》一書,代碼採用Java語言。html

更多:《劍指Offer》Java實現合集  java

題目

  給定一個數組和滑動窗口的大小,請找出全部滑動窗口裏的最大值。例如,若是輸入數組{2, 3, 4, 2, 6, 2, 5, 1}及滑動窗口的大小3,那麼一共存在6個滑動窗口,它們的最大值分別爲{4, 4, 6, 6, 6, 5}數組

思路

  蠻力直接在每一個滑動窗口依次比較找出最大值,時間複雜度過高。post

  咱們考慮把每一個可能成爲最大值的數字記錄下來,就能夠快速的獲得最大值。測試

  思路:創建一個兩端開口的隊列,放置全部多是最大值的數字(存放的實際上是對應的下標),且最大值位於隊列開頭。從頭開始掃描數組,url

  若是遇到的數字比隊列中全部的數字都大,那麼它就是最大值,其它數字不多是最大值了,將隊列中的全部數字清空,放入該數字,該數字位於隊列頭部;spa

  若是遇到的數字比隊列中的全部數字都小,那麼它還有可能成爲以後滑動窗口的最大值,放入隊列的末尾;htm

  若是遇到的數字比隊列中最大值小,最小值大,那麼將比它小數字不可能成爲最大值了,刪除較小的數字,放入該數字。blog

  因爲滑動窗口有大小,所以,隊列頭部的數字若是其下標離滑動窗口末尾的距離大於窗口大小,那麼也刪除隊列頭部的數字。隊列

  :隊列中存放的是下標,以上講的 隊列頭部的數字 均指 隊列頭部的下標所指向的數字。寫代碼時不要弄混了。

 

測試算例 

  1.功能測試(數組數字遞增、遞減、無序)

  2.邊界值測試(滑動窗口大小位0、一、大於或者等於數組長度)

  3.特殊輸入測試(null)

Java代碼

//題目:給定一個數組和滑動窗口的大小,請找出全部滑動窗口裏的最大值。例如,
//若是輸入數組{2, 3, 4, 2, 6, 2, 5, 1}及滑動窗口的大小3,那麼一共存在6個
//滑動窗口,它們的最大值分別爲{4, 4, 6, 6, 6, 5},

public class MaxInSlidingWindow {
    public ArrayList<Integer> maxInWindows(int [] num, int size){
        ArrayList<Integer> max = new ArrayList<Integer>();
        if(num==null || num.length<=0 || size<=0 || size>num.length)
            return max;
        ArrayDeque<Integer> indexDeque = new ArrayDeque<Integer>();
        
        for(int i=0;i<size-1;i++){
            while(!indexDeque.isEmpty() && num[i]> num[indexDeque.getLast()])
                indexDeque.removeLast();
            indexDeque.addLast(i);
        }
        
        for(int i=size-1;i<num.length;i++){
            while(!indexDeque.isEmpty() && num[i]> num[indexDeque.getLast()])
                indexDeque.removeLast();
            if(!indexDeque.isEmpty() && (i-indexDeque.getFirst())>=size)
                indexDeque.removeFirst();
            indexDeque.addLast(i);
            max.add(num[indexDeque.getFirst()]);
        }
        
        return max;
    }
}

  

  

收穫

  1.本身最初想到的是隻存放最大的數,沒有想到能夠存放全部多是最大的數,要記住。

  2.ArrayDeque——雙端隊列,要記住。下面是一些經常使用的方法:

 

 

  

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索