Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Return the max sliding window.
Example:
Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
Output: [3,3,5,5,6,7]
Explanation:
Window position Max
--------------- -----
[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
Note:
You may assume k is always valid, 1 ≤ k ≤ input array's size for non-empty array.
Follow up:
Could you solve it in linear time?
代码
Approach 1: Use a hammer (TLE)
Complexity Analysis
Time complexity : O(Nk), where N is number of elements in the array.
Space complexity : O(N-k+1) for an output array.
classSolution {publicint[] maxSlidingWindow(int[] nums,int k) {int n =nums.length;if (n * k ==0) returnnewint[0];int[] output =newint[n - k +1];for (int i =0; i < n - k +1; i++) {int max =Integer.MIN_VALUE;for (int j = i; j < i + k; j++) { max =Math.max(max, nums[j]); } output[i] = max; }return output; }}
Approach 2: Deque
Deque 每次将最大的元素的index放在首位
classSolution {ArrayDeque<Integer> deq =newArrayDeque<Integer>();int[] nums;publicint[] maxSlidingWindow(int[] nums,int k) {int n =nums.length;if (n * k ==0) returnnewint[0];if (k ==1) return nums;this.nums= nums;int max_idx =0;for (int i =0; i < k; i++) {cleanDeque(i, k);deq.addLast(i);if (nums[i] > nums[max_idx]) { max_idx = i; } }int[] output =newint[n - k +1]; output[0] = nums[max_idx];for (int i = k; i < n; i++) {cleanDeque(i, k);deq.addLast(i); output[i - k +1] = nums[deq.getFirst()]; }return output; }publicvoidcleanDeque(int i,int k) {// remove indexes of elements not from sliding windowif (!deq.isEmpty() &&deq.getFirst() == i - k) {deq.removeFirst(); }// remove from deq indexes of all elements// which are smaller than current elemnt num[i]while (!deq.isEmpty() && nums[i] > nums[deq.getLast()]) {deq.removeLast(); } }}
Approach #3 Dynamic programming
[i % k == 0, ~ i] 中左边block的最大值赋值给 left[i], 边界右
[i, i % k == 0] 中右边block的最大值赋值给 right[i],边界左
Complexity Analysis
Time complexity : O(N), since all we do is 3 passes along the array of length N.
Space complexity : O(N) to keep left and right arrays of length N, and output array of length N - k + 1.
classSolution {publicint[] maxSlidingWindow(int[] nums,int k) {int n =nums.length;if (n * k ==0) returnnewint[0];if (k ==1) return nums;int[] left =newint[n]; left[0] = nums[0];int[] right =newint[n]; right[n -1] = nums[n -1];for (int i =1; i < n; i++) {if (i % k ==0) { left[i] = nums[i]; } else { left[i] =Math.max(left[i -1], nums[i]); }int j = n - i -1;if ((j +1) % k ==0) { right[j] = nums[j]; } else { right[j] =Math.max(right[j +1], nums[j]); }int[] output =newint[n - k +1];for (int i =0; i < n - k +1; i++) { output[i] =Math.max(left[i + k -1], right[i]); }return output; }}