《剑指offer》JZ64滑动窗口的最大值

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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个数,依次输入,如果num[i]>num[i-1],则将num[i-1]删掉;如果num[i] <= num[i-1],则存储;然后将最大值存入res中

②滑动窗口,首先判断滑动前窗口中的最大值是不是位于窗口首部,如果位于窗口首部,则删除;

   然后开始加入数字,判断当前数字是不是比滑动前窗口尾部数字大,如果大的话,则将滑动前窗口尾部数字删掉(因为其不可能为最大值了),然后将当前数字加入;

③重复上述步骤;

代码:

import java.util.*;
public class Solution {
    public ArrayList maxInWindows(int [] num, int size)
    {
        //存放结果
        ArrayList res = new ArrayList<>();
        //队首存放当前窗口最大值
        LinkedList queue = new LinkedList<>();
        if(num.length == 0 || size == 0 || size > num.length){
            return res;
        }
        //为了判断是否超出范围,所以queue中存放数字下标
        for(int i = 0; i < num.length; i++){
            //如果要进入窗口的数字比之前窗口尾部的数字大,那么窗口尾部的数字永远不可能是最大值
            //则将窗口尾部的数字删掉
            while(!queue.isEmpty() && num[queue.peekLast()] < num[i]){
                queue.pollLast();
            }
            queue.add(i);
            //如果队首数字超过窗口首部,则将去出队
            if(queue.peekFirst() == i-size){
                queue.pollFirst();
            }
            //queue中包含了size个数字之后,才开始将最大值存入res
            if(i >= size-1){
                res.add(num[queue.peekFirst()]);
            }
        }
        return res;
    }
}

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