標籤:
Sliding Window Maximum
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.
For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.
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
Therefore, return the max sliding window as [3,3,5,5,6,7].
Note:
You may assume k is always valid, ie: 1 ≤ k ≤ input array‘s size for non-empty array.
Follow up:
Could you solve it in linear time?
Hint:
- How about using a data structure such as deque (double-ended queue)?
- The queue size need not be the same as the window’s size.
- Remove redundant elements and the queue should store only elements that need to be considered
https://leetcode.com/problems/sliding-window-maximum/
首先是非線性複雜度的解法,直接用js的數組來類比雙向隊列。
1 /** 2 * @param {number[]} nums 3 * @param {number} k 4 * @return {number[]} 5 */ 6 var maxSlidingWindow = function(nums, k) { 7 var window = [], result = []; 8 for(var i = 0; i < nums.length; i++){ 9 if(window.length === k){10 result.push(findMax(window));11 window.shift();12 }13 window.push(nums[i]);14 }15 if(window.length === k){16 result.push(findMax(window));17 }18 return k !== 0 ? result : [];19 20 function findMax(arr){21 var max = -Infinity;22 for(var i = 0; i < arr.length; i++){23 if(arr[i] > max){24 max = arr[i];25 }26 }27 return max;28 }29 };
線性複雜度的解法。
https://leetcode.com/discuss/46578/java-o-n-solution-using-deque-with-explanationa
核心思想就是在隊列頭儲存最大元素的下標。
每一輪迴圈:
1.先移除到期的元素;
2.從後往前移出不可能是結果的元素,兩種情況:
i)比如隊列是[2,3],這一輪的元素是4,那麼max一定是4,2和3都可以移除了;
ii)比如隊列是[5,3],這一輪的元素是4,那麼要移出3,最後的結果應該是[5,4]。
因為等5到期了,4可能就是最大的元素了,所以要放著。為什麼可以放心地移除3呢,因為4的到期時間肯定比3久,而且大於3。 <-- 此處是痛點
3.往隊列裡放入這一輪的元素,如果長度大於等於視窗長度與就輸出。
儲存下標而非值是為了之後可以方便地找出到期的元素,需要值的時候直接可以通過下標訪問nums。
1 /** 2 * @param {number[]} nums 3 * @param {number} k 4 * @return {number[]} 5 */ 6 var maxSlidingWindow = function(nums, k) { 7 var window = [], index = -1, result = []; 8 for(var i = 0; i < nums.length; i++){ 9 while(window.length !== 0 && window[0] < i - k + 1){10 window.shift();11 }12 while(window.length !== 0 && nums[window[window.length - 1]] < nums[i]){13 window.pop();14 }15 window.push(i);16 if(i >= k - 1){17 result.push(nums[window[0]]);18 }19 }20 return result; 21 };
[LeetCode][JavaScript]Sliding Window Maximum