Sliding Window Maximum

Source: Internet
Author: User

From https://leetcode.com/problems/sliding-window-maximum/


Given an array nums, there is a sliding window of size K which are moving from the very left of the array To the very right. You can only see the K numbers in the window. Each of 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] &nbsP;    7 

Therefore, return the max sliding window as [3,3,5,5,6,7] .

Here are some questions to consider intuitively:

  1. Do not directly record the maximum value in the sliding process, record the subscript of the maximum value, assuming that the subscript is J, and the value is X, because in the next calculation, you need to know whether the subscript is in the current window, and then read into the next element, assuming y; Then there are three things to consider:

    A. If y > x; Then y must be the maximum value of the current window (why?). );

    B. If y < X, and J + K >= I (current coordinates), then x is the maximum value of the current window;

    C. If y < X, and J + K < I; That is, the previous maximum has been moved out of the current window, this time you need to calculate the maximum value in the current window;

    So according to this can implement the following code, you can see in the third case is only the order to find the maximum value in the window, simple analysis can get the worst case of the need O (n * k) time;


  2. Public int[] maxslidingwindow1 (int[] nums, int k)  {    int  n = nums.length;    if  (n == 0)  {         return new int[0];    }    int [] result = new int[n - k + 1];    int index  = 0;    for  (int i = 1; i < k; i++)  {        if  (Nums[result[index]] < nums[i])  {            result[index] = i;         }    }    for  ( int i = k; i < n; i++)  {         int j = result[index++];        int a = nums[j];         int b = nums[i];         if  (B >= a)  {             result[index] = i;        } else {             if  (i - j < k)  {                result[ index] = j;            } else  {                result[index]  = j + 1;                 for&nbsp (int m = j + 2; m <= i; m++)  {                     if  (Nums[result[index]] < nums[m])  {                         result[index] =  m;                     }                 }            }         }    }    for  (int i = 0; i  < result.length; i++)  {        result[i]  = nums[result[i]];    }    return result;} 
  3. Of course there are areas for improvement; Consider such an input (part) 5, 3, 1, 2, 1, Window size 3, (result 5, 3, 2);   then simulate the above algorithm starting from 1:

    A. Read in 1, the previous maximum value is 5, and in the window, so the current window maximum value is 5;

    B. Read 2, the maximum value is 5 out of the window, so to calculate the maximum from # and get 3;

    C. read in 1, maximum 3 out of the window, so from # 2 start recalculation and get 2;

    So is there a way to do without the input that has already been processed for repeated processing? The answer is naturally there. Consider using a stack, which holds a sequence of descending (coordinates). When processing to a certain location, because the stack is in the following value (if present) is certainly larger than the current value, so long as the bottom of the stack, and in the current window of the value is the maximum value of the current window; the

    Code is as follows:


  4. Public int[] maxslidingwindow (int[] nums, int k)  {    int  n = nums.length;    if  (n == 0)  {         return new int[0];    }    int [] result = new int[n - k + 1];    stack< Integer> stack = new stack<> (), temp = new stack<> ();     result[0] = nums[0];    stack.push (0);     for  (int i = 1; i < k; i++)  {         if  (Result[0] < nums[i])  {             result[0] = nums[i];         }         int a = nums[i];        while   (!stack.isempty ()  && nums[stack.peek ()] < a)  {             stack.pop ();         }        stack.push (i);    }     int index = 1;    for  (int i = k; i  < n; i++)  {        int a = nums [i];        while  (!stack.isempty ()  && nums[ Stack.peek ()] < a)  {             Stack.pop ();        }         if  (Stack.isempty ()) &NBSp {            result[index++] = a;         } else {             if  (Stack.peek ()  + k <= i)  {                 result[index++] = a;             } else {                 while  (!stack.empty ()  & & stack.peek ()  + k > i)  {                     temp.push (Stack.pop ());                 }        &nBsp;        result[index++] = nums[temp.peek ()];                 while  (!temp.empty ())  {                     stack.push (Temp.pop ());                 }            }         }        stack.push (i);     }    return result;}
  5. Simple analysis: Or 5, 3, 1, 2, 1 as an example;

    A. When processing to 1, the stack inside is 5, 3 (should be coordinates, in order to see clearly, directly with the value substitution), and 5 in the window, so the current window maximum value of 5;stack to 5, 3, 1;

    B. When dealing with 2, the 1 smaller than 2 will be dropped by pop, and Stack becomes 5, 3, 2; Then 3 is the bottom value of the current window, so the maximum value is 3;

    C. When dealing with the last 1, the maximum of the current window in the stack is 2, so the maximum value is 2, and the preceding algorithm needs to be processed from 1, where it is only necessary to handle to 2.

  6. Performance

    But after submission, the algorithm 1 time is 500MS, algorithm 2 is 700ms;sign~~~~

    Simple analysis, the algorithm 1 uses only the array, and the algorithm 2 uses the stack, and the algorithm 2 uses two stacks, to find the maximum value in the current window, in fact, if you define a data structure, you can use only one; Assuming that a stack is used, then each element is stacked once, up to the stack, worst case for example a descending sequence, and unfortunately, the time complexity is still O (n * k);

  7. Another optimization is that the stack retains only the maximum value of the previous window and the descending sequence of the current window, finding the largest element in the current window can be completed in constant time, can achieve the complexity of O (n);





Sliding Window Maximum

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.