【剑指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);
        }
    }
}

你可能感兴趣的:(剑指offer)