问题描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5};
问题解答
设立begin为滑动窗口的前索引,i为后索引。那么当begin>=0时 此时滑动窗口最大值才有意义。
用双端队列来存储数组的索引信息,把当前最大值的索引维持在队首
如果最新的值从队尾开始比较 如果比队尾的元素大,则把队尾的元素poll掉
这样可以保持 队内的元素都是比当前值大 而且 用begin>队首的索引如果当前最大值过期了 可以淘汰掉 之后的值就成为了队首。
如果滑动窗口有意义 则把队首的元素索引对应的值放入返回列表。
import java.util.*;
/**
* 用一个双端队列,队列第一个位置保存当前窗口的最大值,当窗口滑动一次
* 1.判断当前最大值是否过期
* 2.新增加的值从队尾开始比较,把所有比他小的值丢掉
*/
public class Solution {
public static ArrayList<Integer> maxInWindows(int[] num, int size) {
ArrayList<Integer> ret = new ArrayList<>();
if (num == null || size == 0)
return ret;
int begin;
ArrayDeque<Integer> arrayDeque = new ArrayDeque<>();
for (int i = 0; i < num.length; i++) {
begin = i - size + 1;
if (arrayDeque.isEmpty())
arrayDeque.add(i);
else if (begin>arrayDeque.peekFirst())
arrayDeque.pollFirst();
while (!arrayDeque.isEmpty()&&num[i]>=num[arrayDeque.peekLast()])
arrayDeque.pollLast();
arrayDeque.add(i);
if (begin>=0)
ret.add(num[arrayDeque.peekFirst()]);
}
return ret;
}
}