给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 输出:[3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1 输出:[1]
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
我们需要维护一个单调递减的双端队列, 队列中存放元素的下标, 这样, 队头元素是当前窗口的最大值
另外我们需要保证移除时, 移除过期元素和冗余元素 :
过期元素 :
冗余元素 :
完整流程如下 :
队头元素是当前窗口的最大值 :
如上图 :
基本思路是 :
如上图所示, 第一个元素 9 是第一个窗口的最大的元素, 但是当移动到第二个窗口的时候, 它就不是第二个窗口中最大的元素值了 , 我们要把它移除掉, 对应的代码是 :
// 队头过期 : // 队头元素已经不在窗口内了 // i 是队尾元素, i - k 是最后一个元素 // 队头过期肯定是在第二个窗口才会出现过期的现象 while (!deque.isEmpty() && deque.getFirst() <= i - k) { // 返回并删除队列头元素 deque.removeFirst(); }
package leetcode.editor.cn; import java.util.ArrayDeque; import java.util.Deque; /** * 滑动窗口最大值 * * @author * @date 2022-10-04 18:19:29 */ @SuppressWarnings("all") public class SlidingWindowMaximum { public static void main(String[] args) { //测试代码 Solution solution = new SlidingWindowMaximum().new Solution(); int[] nums = new int[]{1, 3, -1, -3, 5, 3, 6, 7}; int k = 3; solution.maxSlidingWindow(nums, k); } //leetcode submit region begin(Prohibit modification and deletion) class Solution { public int[] maxSlidingWindow(int[] nums, int k) { int[] ans = new int[nums.length - k + 1]; int index = 0; // 双端队列, 存储下标 Deque<Integer> deque = new ArrayDeque<>(); for (int i = 0; i < nums.length; i++) { // 队头过期 : // 队头元素已经不在窗口内了 while (!deque.isEmpty() && deque.getFirst() <= i - k) { // 返回并删除队列头元素 deque.removeFirst(); } // 如果nums[i] > nums[deque.getLast()] // 说明队列中 前面的元素就都没用了, 因为 nums[i] 要比前面的元素都大 // 我们就要移除前面的元素, 要保证队头元素是最大的! while (!deque.isEmpty() && nums[deque.getLast()] <= nums[i]) { // 移除队尾元素 deque.removeLast(); } deque.addLast(i); // 取队头更新元素 if (i >= k - 1) { ans[index] = nums[deque.getFirst()]; index++; } } return ans; } } //leetcode submit region end(Prohibit modification and deletion) }
本文作者:兀坐晴窗独饮茶
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!