Sliding Window Maximum LT239

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?

Idea 1. Sliding window, borrow the idea of montone increasing queue, moving two pointers.
右边界向右边滑,扫新的元素, 
  •  pop out all nums[j] if nums[right] > nums[j] (j < i), 因为新的数大,窗口中前面的小数不可能是窗口的max value, 形成一个递减的queue, the queue head is the local maximum in the current window;
  • push nums[right]
左边界向右边滑,
        pop out nums[left] if deque.peekFirst == nums[left], 如果左边界是最大值,向右移左边届已经不在有效窗口内,需要从queue头移除最大值
Since pop operation needed on both ending, deque is a suitable struct.
Time complexity: O(n) since each element is only pushed once and poped out once from the deque.
Space complexity: O(n)
1.a deque store the array item
 1 class Solution {
 2     public int[] maxSlidingWindow(int[] nums, int k) {
 3         if(nums.length == 0 || k > nums.length) {
 4             return new int[0];
 5         }
 6         
 7         Deque<Integer> maxBuffer = new LinkedList<>();
 8         int[] result = new int[nums.length - k + 1];
 9         
10         for(int left = 0, right = 0; right < nums.length; ++right) {  
11             while(!maxBuffer.isEmpty() && nums[right] > maxBuffer.peekLast()) {
12                 maxBuffer.pollLast();
13             }
14             maxBuffer.offerLast(nums[right]);
15             if(right >= k-1) {
16                 result[left] = maxBuffer.peekFirst();
17                 if(nums[left] == result[left]) {
18                     maxBuffer.pollFirst();
19                 }
20                 ++left;
21             }
22         }
23         
24         return result;
25     }
26 }

python

 1 class Solution:
 2     def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
 3         maxBuffer = collections.deque()
 4         
 5         result = []
 6         for right in range(len(nums)):
 7             while maxBuffer and maxBuffer[-1] < nums[right]:
 8                 maxBuffer.pop()
 9                 
10             maxBuffer.append(nums[right])
11             if right >= k - 1:
12                 result.append(maxBuffer[0])
13             
14                 if maxBuffer[0] == nums[right - k + 1]:
15                     maxBuffer.popleft()
16                 
17         return result

1.b deque store the array index, instead,

 1 class Solution {
 2     public int[] maxSlidingWindow(int[] nums, int k) {
 3         if(nums.length == 0 || k > nums.length) {
 4             return new int[0];
 5         }
 6         
 7         int[] result = new int[nums.length - k + 1];
 8         Deque<Integer> maxIndexBuffer = new ArrayDeque();
 9         for(int left = 0, right = 0; right < nums.length; ++right) {
10             while(!maxIndexBuffer.isEmpty() && nums[maxIndexBuffer.peekLast()] < nums[right] ) {
11                 maxIndexBuffer.pollLast();
12             }
13             maxIndexBuffer.offerLast(right);
14             
15             if(right >= k-1) {
16                 int maxIndex = maxIndexBuffer.peekFirst();
17                 result[left] = nums[maxIndex];
18                 
19                 if(maxIndex == left) {
20                     maxIndexBuffer.pollFirst();
21                 }
22                 ++left;
23             }
24         }
25         
26         return result;
27     }
28 }

python

 1 class Solution:
 2     def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
 3         maxIndex = collections.deque()
 4         
 5         result = []
 6         for right in range(len(nums)):
 7             while maxIndex and nums[maxIndex[-1]] < nums[right]:
 8                 maxIndex.pop()
 9                 
10             maxIndex.append(right)
11             if right >= k - 1:
12                 result.append(nums[maxIndex[0]])
13             
14             if maxIndex[0] == right - k + 1:
15                 maxIndex.popleft()
16                 
17         return result

猜你喜欢

转载自www.cnblogs.com/taste-it-own-it-love-it/p/10582487.html
今日推荐