【劍指offer】64. 滑動窗口的最大值

問題描述

給定一個數組和滑動窗口的大小,找出所有滑動窗口裏數值的最大值。例如,如果輸入數組{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]}。

思路

這題是字節跳動測試開發實習生面試題原題。寫出來O(n2)的算法很容易。(方法一)
但是寫出來更優化的就難點了。 怎麼做? 我想到過用單調棧,但是單調棧不好使。因爲我們要維護的是局部最優。那咋整呢?我們可以設置一個max 和 maxIndex, max記錄最大值,maxIndex記錄最大值的下標。如果maxIndex在滑動窗口的範圍內,且新加入滑動窗口的元素不如max大,則直接加入max到res。 如果大於等於max,則更新max和maxIndex的值,再將max加入res。爲什麼等於max也要更新max和maxIndex的值? 因爲值相等,記錄靠右的,有利於我們維持這個最大值的統治範圍。(方法二)

方法一

import java.util.*;
public class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size){
        ArrayList<Integer> res = new ArrayList<>();
        if(num == null || num.length == 0 || size < 1 || num.length < size) return res;
        for(int i = 0; i <= num.length-size; i++) res.add(getMax(num,i,i+size));
        return res;
    }
    private int getMax(int[] num, int left, int right){
        int max = Integer.MIN_VALUE;
        for(;left<right;left++) max = Math.max(max,num[left]);
        return max;
    }
}

方法二

class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size) {
        ArrayList<Integer> res = new ArrayList<>();
        if(num == null || num.length == 0 || size < 1 || num.length < size) return res;
        initRes(res, num, size);
        return res;
    }
    private void initRes(ArrayList<Integer> res, int[] num, int size){
        int max = Integer.MIN_VALUE, maxIndex = -1;
        for(int i = size-1; i < num.length; i++){
            if(maxIndex < i-size+1){
                // max不在滑動窗口內
                max = num[i-size+1];
                maxIndex = i-size+1;
                for(int j = i-size+1; j <= i; j++){
                    if(max <= num[j]){
                        max = num[j];
                        maxIndex = j;
                    }
                }
            }else{
                // max在滑動窗口內
                if(num[i] >= max){ // 更新最大值
                    max = num[i];
                    maxIndex = i;
                }
            }
            res.add(max);
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章