来源Leetcode第239题滑动窗口中的最大值
给定一个数组 nums ,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。示例:
1 2 3 4 5 6 7 8 9 10 11 12 输入: 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
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。
暴力遍历 思路同重复元素III,在数组中划定长度为k的滑动窗口,通过2重循环,依次找到每个滑动窗口里的最大值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public int [] maxSlidingWindow(int [] nums, int k) { int len = nums.length; if (len * k == 0 ) return new int [0 ]; int [] ans = new int [len - k + 1 ]; int max = Integer.MIN_VALUE; for (int i = 0 ; i < len - k + 1 ; i++){ max = Integer.MIN_VALUE; for (int j = i; j < i + k; j++) max = Math.max(max,nums[j]); ans[i] = max; } return ans; }
单调队列 来源
「单调队列」的核心思路和「单调栈」类似。单调队列的 push 方法依然在队尾添加元素,但是要把前面比新元素小的元素都删掉.
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 class deque { private LinkedList<Integer> data; public void push (int n) { while (!data.isEmpty() && data.getLast() < n) data.removeLast(); data.addLast(n); } public int max () { return data.getFirst(); } public void pop (int n) { if (!data.isEmpty() && data.getFirst() ==n) data.removeFirst(); } public deque () { data = new LinkedList <>(); } } public int [] maxSlidingWindow(int [] nums, int k) { int len = nums.length; if (len * k == 0 ) return new int [0 ]; int [] ans = new int [len - k + 1 ]; deque window = new deque (); for (int i = 0 ; i < nums.length; i++){ if (i < k - 1 ) window.push(nums[i]); else { window.push(nums[i]); ans[i - k + 1 ] = window.max(); window.pop(nums[i-k+1 ]); } } return ans; }
遍历 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 49 50 51 52 53 54 55 public int [] maxSlidingWindow(int [] nums, int k) { if (nums.length * k == 0 ){ return new int [0 ]; } int [] ans=new int [nums.length-k+1 ]; if (nums.length<k){ return new int []{}; } int begin=0 ; int end=k-1 ; int count=0 ; int max=Integer.MIN_VALUE; int stand=0 ; for (int i=0 ;i<=k-1 ;i++){ if (max<nums[i]){ max=nums[i]; stand=i; } } ans[count]=nums[stand]; count++; begin++; end++; while (end<nums.length){ if (nums[end]>max){ max=nums[end]; stand=end; } if (begin>stand){ max=Integer.MIN_VALUE; for (int i=begin;i<=end;i++){ if (max<nums[i]){ max=nums[i]; stand=i; } } } ans[count]=nums[stand]; count++; begin++; end++; } return ans; }