Time: 2019/4/16
Title: Sliding Window Maximum
Difficulty: Difficulty
Author: Little Deer
Title: 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. Return the max sliding window.
Given an array nums, a sliding window of size k moves from the leftmost side of the array to the rightmost side of the array. You can only see the numbers in the sliding window K. The sliding window moves one bit to the right at a time.
Returns the maximum 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?
Solve:
_Problem Analysis
brute-force attack
1) Violent cracking is the easiest way to think about this topic. With the help of a for loop, two variables, the whole window is moved, and then every time it moves, the maximum value is found in the window of size k.
2) But such a solution is very inefficient. If the data is very large, there are N1 data, the window size is N2 (n1 is much larger than n2), and the time complexity is n2(n1 - n2). That is n1 * n2, and the worst time complexity is n^2.
Priority queue
1) Every time we get the maximum value of moving window and dynamic data, we think of priority queue, and the realization of priority queue is the data structure of heap, which is more efficient to solve this problem with heap. If you are not familiar with heap, make up for your homework! There is a link to my article at the bottom.
2) By optimizing the heap, the time complexity of inserting data into the heap is logn, so the time complexity is nlogn.
_ALGORITHM THINKING
Violent cracking:
1) Use two pointers to point to the start and end of the window respectively, then traverse the data in the window to get the maximum value; move two pointers forward, and then operate until the traversal data is completed.
Priority queue:
1) It is necessary to maintain a large top heap with size K. The top of the heap is the largest data of the current window. When moving the window, if the data inserted is larger than the data on the top of the heap, it is added to the result set. At the same time, to delete the data, if the deleted data is the largest data and the inserted data is smaller than the deleted data, the time complexity of logn with size k is inserted, and the top element is returned.
_Violent Solution
var maxSlidingWindow = function(nums, k) { if(k > nums.length || k === 0) return []; let res = [], maxIndex = -1; for(let l = 0, r = k-1;r < nums.length;l++, r++){ if(maxIndex < l){ // Traverse to find the maximum let index = l; for(let i = l;i <= r;i++) { if(nums[i] > nums[index]) index = i; } maxIndex = index; } if(nums[r] > nums[maxIndex]){ maxIndex = r; } res.push(nums[maxIndex]); } return res; };
_Priority Queue
let count = 0; let heap = []; let n = 0; var maxSlidingWindow = function(nums, k) { let pos = k; n = k; let result = []; let len = nums.length; // Determine whether the array and the maximum window tree are empty if(nums.length === 0 || k === 0) return result; // Building top pile let j = 0 for(;j < k; j++){ insert(nums[j]); } result.push(heap[1]); // move windows while(len - pos > 0){ if(nums[k] > heap[1]){ result.push(nums[k]); insert(nums[k]); nums.shift(); pos++; }else{ if(nums.shift() === heap[1]){ removeMax(); } insert(nums[k-1]); result.push(heap[1]); pos++; } } return result; }; // insert data const insert = (data) =>{ //Judgment stack // if(count >= n) return; // >= // Insert to the end of the array count++ heap[count] = data; //Bottom-up heaping let i = count; while(i / 2 > 0 && heap[i] > heap[parseInt(i/2)]){ swap(heap,i,parseInt(i/2)); i = parseInt(i/2); } } // Element Exchange in Two Arrays swap = (arr,x,y) =>{ let temp = arr[x]; arr[x] = arr[y]; arr[y] = temp; } // Deletion of heap const removeMax = () =>{ // Judge heap space if(count <= 0) return ; // Move the maximum data to the last deletion heap[1] = heap[count]; // Length minus one count--; // Delete data heap.pop(); // From top to bottom heaping heapify(heap,count,1); } // From top to bottom heaping const heapify = (heap,count,i) =>{ while(true){ // Maximum subscripts for storage heap subnodes let maxPos = i; // Left child node is larger than parent node if(i*2 < n && heap[i*2] > heap[i]) maxPos = i*2; // The right child node is larger than the parent node if(i*2+1 <= n && heap[i*2+1] > heap[maxPos]) maxPos = i*2+1; // If no substitution occurs, it means that the heap has only one node (parent node) or that the child node is smaller than the parent node. if(maxPos === i) break; // exchange swap(heap,maxPos,i); // Continuous stacking i = maxPos; } }
_Performance Analysis
brute-force attack
- Time complexity: O (n^2).
- Spatial complexity: O(1).
Priority queue
- Time complexity: nlogn.
- Spatial complexity: O(1).
Extension
Heap:
1) heap insertion and deletion operations
2) How to implement a heap?
3) heap sorting
4) Application of Reactor
Check out another article about heap written in detail: The Beauty of Data Structure and Algorithms
Welcome to join the LeetCode Open Source Github repository, where you can submit your code in other languages to me. Insist on punching cards with small partners in the warehouse, and improve our open source small warehouse together! __________
Github: https://github.com/luxiangqia...
Welcome to pay close attention to my personal public number: "An Unwilling ordinary farmer", which records the story of self-taught programming along the way.