1. 程式人生 > >滑動視窗的最大值(java版)

滑動視窗的最大值(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]}。

【解題思路1】暴力法
//1. 遍歷求出每個滑動視窗
//2. 在每個滑動視窗中求出最大值,記錄下來。
//3. 注意邊界情況的處理,如:輸入的陣列為null,或者為空;滑動視窗的大小為零,或者大於陣列長度等。

import java.util.ArrayList;

public class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size)
    {
        ArrayList<Integer> arr = new ArrayList<Integer>();
        if(num==null || num.length==0 || size==0){
            return arr;
        }
        int len=num.length, inx=0
, end=len-1; if(size>len){ return arr; }else if(size==len){ arr.add(maxNum(num, 0, len-1)); }else{ for(int i=0; i<len; i++){ inx = i; end = inx+size-1; if(end >= len){ break
; }else{ arr.add(maxNum(num, inx, end)); } } } return arr; } //求幾個值中的最大值 public int maxNum(int[] num, int inx, int end){ int max = num[inx]; for(int i=inx; i<=end; i++){ if(num[i]>max){ max = num[i]; } } return max; } }

【解題思路2】
//1. 滑動視窗應當是佇列,但為了得到滑動視窗的最大值,佇列序可以從兩端刪除元素,因此使用雙端佇列。
//2. 對新來的元素k,將其與雙端佇列中的元素相比較, 前面比k小的,直接移出佇列(因為不再可能成為後面滑動視窗的最大值了!
//3. 前面比k大的X,比較兩者下標,判斷X是否已不在視窗之內,不在了,直接移出佇列。佇列的第一個元素是當前滑動視窗中的最大值

【實現一】

public ArrayList<Integer> maxInWindows(int [] num, int size)
    {
        ArrayList<Integer> ret = new ArrayList<>();
        if (num == null) {
            return ret;
        }
        if (num.length < size || size < 1) {
            return ret;
        }

        LinkedList<Integer> indexDeque = new LinkedList<>();
        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();
            }
            indexDeque.addLast(i);
            if (i - indexDeque.getFirst() + 1 > size) {
                indexDeque.removeFirst();
            }
            ret.add(num[indexDeque.getFirst()]);
        }
        return ret;
    }

【實現二】

public ArrayList<Integer> maxInWindows(int [] num, int size)
    {
        ArrayList<Integer> res = new ArrayList<>();
        if(size == 0) return res;
        int begin;  
        ArrayDeque<Integer> q = new ArrayDeque<>();
        for(int i = 0; i < num.length; i++){
            begin = i - size + 1;
            if(q.isEmpty())
                q.add(i);
            else if(begin > q.peekFirst())
                q.pollFirst();
         
            while((!q.isEmpty()) && num[q.peekLast()] <= num[i])
                q.pollLast();
            q.add(i);   
            if(begin >= 0)
                res.add(num[q.peekFirst()]);
        }
        return res;
    }