LeetCode's JavaScript Solution to Question 239: Sliding Window Maximum

Keywords: Javascript github Windows Programming

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.

Posted by teddirez on Thu, 09 May 2019 18:12:39 -0700