239_滑动窗口最大值
package 队列.queue; import java.util.ArrayDeque; import java.util.Deque; import java.util.LinkedList; import java.util.Queue; /** * https://leetcode-cn.com/problems/sliding-window-maximum/ * @author Huangyujun * * 思路: * ① 首先,维护一个单调递减的双端队列 * 实现单调递减: while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) { deque.pollLast(); } * ② 然后,(0 < i < k) 先形成一个窗口【左边界限是0, 右边界限是k-1】 * ③ 存放滑动窗口最大值的结果的数组 int[] ans = new int[n - k + 1]; * 且 ans[0] = 双端队列队头所存储的索引; * ④ 接下来,从 k < i < n, 每走一步,形成一个结果 * 当然,首先是要维持住双端队列是单调递减的特点 * 然后,通过判断队头是否在当前这个窗口范围内,注意是索引哈,形成一个新窗口时,这个窗口【左边界限是i - k, 右边是。。。】,把旧窗口的最大值poll掉 * 最后,就是当前走的这一步的结果添加到结果数组 * *https://leetcode-cn.com/problems/sliding-window-maximum/solution/dong-hua-yan-shi-dan-diao-dui-lie-239hua-hc5u/ */ public class _239_滑动窗口最大值 { public int[] maxSlidingWindow(int[] nums, int k) { int n = nums.length; //创建双端队列 Deque<Integer> deque = new LinkedList<Integer>(); //先初始化前K个元素 for (int i = 0; i < k; i++) { //判断队列是否为空 或者当前入队元素是否大于队尾元素 大于则出队 while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) { deque.pollLast(); } //当前元素入队 //由于需要判断当前元素是否在窗口中,所以实际上队列中存储的为当前元素的下标 //根据下标找元素比根据元素找下标方便 deque.offerLast(i); } int[] ans = new int[n - k + 1]; //添加当前最大元素 ans[0] = nums[deque.peekFirst()]; for (int i = k; i < n; i++) { //判断队列是否为空 或者当前入队元素是否大于队尾元素 大于则出队 while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) { deque.pollLast(); } //当前元素入队 deque.offerLast(i); //循环判断队首元素是否在窗口中,窗口的左边界为i-k while (deque.peekFirst() <= i - k) { deque.pollFirst(); } //添加答案 ans[i - k + 1] = nums[deque.peekFirst()]; } return ans; } }