单调队列,入队时要确保不存在逆序
滑动窗口的最大值
http://www.nowcoder.com/questionTerminal/1624bc35a45c42c0bc17d17fa0cba788
窗口形成期(直接加)与窗口形成后(需要判断)。
思路类比最小栈, 不同之处如下:
不同点在于 “出栈操作” 删除的是 “列表尾部元素” ,而 “窗口滑动” 删除的是 “列表首部元素” 。
思路:入队列时,要将队列中比元素小的元素都删粗,这样确保,队列中的第一个元素是最大的!!!!
/** * 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。窗口大于数组长度的时候,返回空 * @param num 数组 * @param size 滑动窗口的大小 * @return 所有滑动窗口里数值的最大值 */ public ArrayList<Integer> maxInWindows(int [] num, int size) { if(size<=0||size>num.length){ return new ArrayList<Integer>(); } //单调队列,添加nums[j+1]时,需要将所有比nums[j+1]小的元素删除,然后再添加!!!,联想minStack() Deque<Integer> deque=new LinkedList<>(); ArrayList<Integer> res=new ArrayList<>(num.length-size+1); //未形成窗口。 for(int i=0;i<size;i++){ while (!deque.isEmpty()&&deque.peekLast()<num[i]){ deque.removeLast(); } deque.addLast(num[i]); } res.add(deque.peekFirst()); //形成窗口后 for(int i=size;i<num.length;i++){ if(deque.peekFirst()==num[i-size]){ deque.removeFirst(); } while (!deque.isEmpty()&&deque.peekLast()<num[i]){ deque.removeLast(); } deque.addLast(num[i]); res.add(deque.peekFirst()); } return res; }