单调队列解决滑动窗口问题
力扣链接:剑指 Offer 59 - I. 滑动窗口的最大值 - 力扣(LeetCode) (leetcode-cn.com)
剑指 Offer 59 - II. 队列的最大值 - 力扣(LeetCode) (leetcode-cn.com)
单调队列
队列中的元素呈现一定的单调性,单调递增或单调递减
滑动窗口问题
指求解在指定范围内的最值问题,并且这个范围还会移动或改变
滑动窗口的最大值
滑动窗口的最大值:剑指 Offer 59 - I. 滑动窗口的最大值 - 力扣(LeetCode) (leetcode-cn.com)
思路
- 构造一个单调递减的队列
- 获取当前队列的首元素即可获取当前窗口的最大值
- 当单调队列中的最大值在滑动窗口范围外,就弹出队首元素
- 当新增元素大于等于队尾元素时,就不断弹出队尾元素,直到队尾元素大于新增元素,再新增元素
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { public int[] maxSlidingWindow(int[] nums, int k) { if (nums.length == 0 || nums.length<k){ return new int[0]; } Deque<Integer> deque = new LinkedList<>(); List<Integer> res = new ArrayList<>(); for (int i = 0; i < nums.length; i++) { if (!deque.isEmpty() && i-deque.peek()>=k){ deque.remove(); } while(!deque.isEmpty() && nums[i]>=nums[deque.peekLast()]){ deque.removeLast(); } deque.add(i); if (i>=k-1){ res.add(nums[deque.peek()]); } } return res.stream().mapToInt(Integer::intValue).toArray(); } }
|
队列的最大值
剑指 Offer 59 - II. 队列的最大值 - 力扣(LeetCode) (leetcode-cn.com)
思路
一个队列用于记录元素,一个单调队列用于记录队列中的最值
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| class MaxQueue { Queue<Integer> queue = null; Deque<Integer> deque = null; public MaxQueue() { queue = new LinkedList<>(); deque = new LinkedList<>(); }
public int max_value() { if (deque.isEmpty()){ return -1; } return deque.peek(); }
public void push_back(int value) { queue.add(value); while (!deque.isEmpty() && deque.peekLast()<=value){ deque.pollLast(); } deque.addLast(value); }
public int pop_front() { if (queue.isEmpty()){ return -1; } if (queue.peek().equals(deque.peekFirst())){ deque.pollFirst(); } return queue.poll(); } }
|