Find maximum of minimum for every window size in a given array - GeeksforGeeks

22 Oct, 2021
Given an integer array of size n, find the maximum of the minimum’s of every window size in the array. Note that window size varies from 1 to n.Example:
 Input: arr[] = {10, 20, 30, 50, 10, 70, 30} Output: 70, 30, 20, 10, 10, 10, 10The first element in the output indicates the maximum of minimums of all windows of size 1. Minimums of windows of size 1 are {10}, {20}, {30}, {50}, {10}, {70} and {30}. Maximum of these minimums is 70The second element in the output indicates the maximum of minimums of all windows of size 2. Minimums of windows of size 2 are {10}, {20}, {30}, {10}, {10}, and {30}. Maximum of these minimums is 30The third element in the output indicates the maximum of minimums of all windows of size 3. Minimums of windows of size 3 are {10}, {20}, {10}, {10} and {10}. Maximum of these minimums is 20Similarly, other elements of output are computed. 
Naive Solution: Brute Force. Approach: A simple brute force approach to solve this problem can be to generate all the windows possible of a particular length say ‘L’ and find the minimum element in all such windows. Then find the maximum of all such elements and store it. Now the length of window is 1<=L<=N. So we have to generate all possible windows of size ‘1’ to ‘N’ and for generating each such window we have to mark the end-points of that window. So for that, we have to use a nested loop for fixing the starting and end point of the window respectively. Therefore there will be a use of triple-nested loop in brute-force approach mainly for fixing the length of the window, starting point and end point.
C++
Java
Python3
C#
PHP
Javascript
// A naive method to find maximum of// minimum of all windows of different// sizes#include <bits/stdc++.h>using namespace std; void printMaxOfMin(int arr[], int n){    // Consider all windows of different    // sizes starting from size 1    for (int k = 1; k <= n; k++) {        // Initialize max of min for        // current window size k        int maxOfMin = INT_MIN;         // Traverse through all windows        // of current size k        for (int i = 0; i <= n - k; i++) {            // Find minimum of current window            int min = arr[i];            for (int j = 1; j < k; j++) {                if (arr[i + j] < min)                    min = arr[i + j];            }             // Update maxOfMin if required            if (min > maxOfMin)                maxOfMin = min;        }         // Print max of min for current        // window size        cout << maxOfMin << " ";    }} // Driver programint main(){    int arr[] = { 10, 20, 30, 50, 10, 70, 30 };    int n = sizeof(arr) / sizeof(arr[0]);    printMaxOfMin(arr, n);    return 0;}
// A naive method to find maximum of// minimum of all windows of different sizes class Test {    static int arr[] = { 10, 20, 30, 50, 10, 70, 30 };     static void printMaxOfMin(int n)    {        // Consider all windows of different        // sizes starting from size 1        for (int k = 1; k <= n; k++) {            // Initialize max of min for current            // window size k            int maxOfMin = Integer.MIN_VALUE;             // Traverse through all windows of            // current size k            for (int i = 0; i <= n - k; i++) {                // Find minimum of current window                int min = arr[i];                for (int j = 1; j < k; j++) {                    if (arr[i + j] < min)                        min = arr[i + j];                }                 // Update maxOfMin if required                if (min > maxOfMin)                    maxOfMin = min;            }             // Print max of min for current            // window size            System.out.print(maxOfMin + " ");        }    }     // Driver method    public static void main(String[] args)    {        printMaxOfMin(arr.length);    }}
# A naive method to find maximum of# minimum of all windows of different sizesINT_MIN = -1000000def printMaxOfMin(arr, n):         # Consider all windows of different    # sizes starting from size 1    for k in range(1, n + 1):                 # Initialize max of min for        # current window size k        maxOfMin = INT_MIN;         # Traverse through all windows        # of current size k        for i in range(n - k + 1):                         # Find minimum of current window            min = arr[i]            for j in range(k):                if (arr[i + j] < min):                    min = arr[i + j]             # Update maxOfMin if required            if (min > maxOfMin):                maxOfMin = min                         # Print max of min for current window size        print(maxOfMin, end = " ") # Driver Codearr = [10, 20, 30, 50, 10, 70, 30]n = len(arr)printMaxOfMin(arr, n) # This code is contributed by sahilshelangia
// C# program using Naive approach to find// maximum of minimum of all windows of// different sizesusing System; class GFG{         static int []arr = {10, 20, 30, 50, 10, 70, 30};         // Function to print maximum of minimum    static void printMaxOfMin(int n)    {                 // Consider all windows of different        // sizes starting from size 1        for (int k = 1; k <= n; k++)        {                         // Initialize max of min for            // current window size k            int maxOfMin = int.MinValue;                 // Traverse through all windows            // of current size k            for (int i = 0; i <= n - k; i++)            {                                 // Find minimum of current window                int min = arr[i];                for (int j = 1; j < k; j++)                {                    if (arr[i + j] < min)                        min = arr[i + j];                }                     // Update maxOfMin if required                if (min > maxOfMin)                    maxOfMin = min;            }                 // Print max of min for current window size            Console.Write(maxOfMin + " ");        }    }         // Driver Code    public static void Main()    {        printMaxOfMin(arr.Length);    }} // This code is contributed by Sam007.
<?php// PHP program to find maximum of// minimum of all windows of// different sizes // Method to find maximum of// minimum of all windows of// different sizesfunction printMaxOfMin($arr, $n){         // Consider all windows of    // different sizes starting    // from size 1    for($k = 1; $k <= $n; $k++)    {                 // Initialize max of min for        // current window size k        $maxOfMin = PHP_INT_MIN;         // Traverse through all windows        // of current size k        for ($i = 0; $i <= $n-$k; $i++)        {                         // Find minimum of current window            $min = $arr[$i];            for ($j = 1; $j < $k; $j++)            {                if ($arr[$i + $j] < $min)                    $min = $arr[$i + $j];            }             // Update maxOfMin            // if required            if ($min > $maxOfMin)            $maxOfMin = $min;        }         // Print max of min for        // current window size        echo $maxOfMin , " ";    }}     // Driver Code    $arr= array(10, 20, 30, 50, 10, 70, 30);    $n = sizeof($arr);    printMaxOfMin($arr, $n); // This code is contributed by nitin mittal.?>
<script> // A naive method to find maximum of// minimum of all windows of different sizes      var arr = [ 10, 20, 30, 50, 10, 70, 30 ];     function printMaxOfMin(n) {        // Consider all windows of different        // sizes starting from size 1        for (k = 1; k <= n; k++) {            // Initialize max of min for current            // window size k            var maxOfMin = Number.MIN_VALUE;             // Traverse through all windows of            // current size k            for (i = 0; i <= n - k; i++) {                // Find minimum of current window                var min = arr[i];                for (j = 1; j < k; j++) {                    if (arr[i + j] < min)                        min = arr[i + j];                }                 // Update maxOfMin if required                if (min > maxOfMin)                    maxOfMin = min;            }             // Print max of min for current            // window size            document.write(maxOfMin + " ");        }    }     // Driver method             printMaxOfMin(arr.length); // This code contributed by aashish1995</script>
Output: 
70 30 20 10 10 10 10
Complexity Analysis:  
Time Complexity: O(n3). As there is a use of triple nested loop in this approach.
Auxiliary Space: O(1) As no extra data structure has been used to store the values.
Efficient Solution: We can solve this problem in O(n) time. The idea is to use extra space. Below are detailed steps.Step 1: Find indexes of next smaller and previous smaller for every element. Next smaller is the nearest smallest element on right side of arr[i]. Similarly, a previous smaller element is the nearest smallest element on the left side of arr[i]. If there is no smaller element on the right side, then the next smaller is n. If there is no smaller on the left side, then the previous smaller is -1.For input {10, 20, 30, 50, 10, 70, 30}, array of indexes of next smaller is {7, 4, 4, 4, 7, 6, 7}. For input {10, 20, 30, 50, 10, 70, 30}, array of indexes of previous smaller is {-1, 0, 1, 2, -1, 4, 4}This step can be done in O(n) time using the approach discussed in next greater element.Step 2: Once we have indexes of next and previous smaller, we know that arr[i] is a minimum of a window of length “right[i] – left[i] – 1”. Lengths of windows for which the elements are minimum are {7, 3, 2, 1, 7, 1, 2}. This array indicates, the first element is minimum in the window of size 7, the second element is minimum in the window of size 3, and so on.Create an auxiliary array ans[n+1] to store the result. Values in ans[] can be filled by iterating through right[] and left[] 
    for (int i=0; i < n; i++)
    {
        // length of the interval
        int len = right[i] - left[i] - 1;

        // arr[i] is a possible answer for
        // this length len interval
        ans[len] = max(ans[len], arr[i]);
    }
We get the ans[] array as {0, 70, 30, 20, 0, 0, 0, 10}. Note that ans[0] or answer for length 0 is useless.Step 3: Some entries in ans[] are 0 and yet to be filled. For example, we know maximum of minimum for lengths 1, 2, 3 and 7 are 70, 30, 20 and 10 respectively, but we don’t know the same for lengths 4, 5 and 6. Below are few important observations to fill remaining entries a) Result for length i, i.e. ans[i] would always be greater or same as result for length i+1, i.e., ans[i+1]. b) If ans[i] is not filled it means there is no direct element which is minimum of length i and therefore either the element of length ans[i+1], or ans[i+2], and so on is same as ans[i] So we fill rest of the entries using below loop. 
    for (int i=n-1; i>=1; i--)
        ans[i] = max(ans[i], ans[i+1]);
Below is implementation of above algorithm.  
C++
Java
Python3
C#
Javascript
// An efficient C++ program to find// maximum of all minimums of// windows of different sizes#include <iostream>#include<stack>using namespace std; void printMaxOfMin(int arr[], int n){// Used to find previous and next smaller    stack<int> s;     // Arrays to store previous and next smaller    int left[n+1];     int right[n+1];     // Initialize elements of left[] and right[]    for (int i=0; i<n; i++)    {        left[i] = -1;        right[i] = n;    }     // Fill elements of left[] using logic discussed on    // https://www.geeksforgeeks.org/next-greater-element/    for (int i=0; i<n; i++)    {        while (!s.empty() && arr[s.top()] >= arr[i])            s.pop();         if (!s.empty())            left[i] = s.top();         s.push(i);    }     // Empty the stack as stack is// going to be used for right[]    while (!s.empty())        s.pop();     // Fill elements of right[] using same logic    for (int i = n-1 ; i>=0 ; i-- )    {        while (!s.empty() && arr[s.top()] >= arr[i])            s.pop();         if(!s.empty())            right[i] = s.top();         s.push(i);    }     // Create and initialize answer array    int ans[n+1];    for (int i=0; i<=n; i++)        ans[i] = 0;     // Fill answer array by comparing minimums of all    // lengths computed using left[] and right[]    for (int i=0; i<n; i++)    {        // length of the interval        int len = right[i] - left[i] - 1;         // arr[i] is a possible answer for this length        // 'len' interval, check if arr[i] is more than        // max for 'len'        ans[len] = max(ans[len], arr[i]);    }     // Some entries in ans[] may not be filled yet. Fill    // them by taking values from right side of ans[]    for (int i=n-1; i>=1; i--)        ans[i] = max(ans[i], ans[i+1]);     // Print the result    for (int i=1; i<=n; i++)        cout << ans[i] << " ";} // Driver programint main(){    int arr[] = {10, 20, 30, 50, 10, 70, 30};    int n = sizeof(arr)/sizeof(arr[0]);    printMaxOfMin(arr, n);    return 0;}
// An efficient Java program to find// maximum of all minimums of// windows of different size import java.util.Stack; class Test{    static int arr[] = {10, 20, 30, 50, 10, 70, 30};         static void printMaxOfMin(int n)    {        // Used to find previous and next smaller        Stack<Integer> s = new Stack<>();              // Arrays to store previous and next smaller        int left[] = new int[n+1];         int right[]  = new int[n+1];              // Initialize elements of left[] and right[]        for (int i=0; i<n; i++)        {            left[i] = -1;            right[i] = n;        }              // Fill elements of left[] using logic discussed on        // https://www.geeksforgeeks.org/next-greater-element/        for (int i=0; i<n; i++)        {            while (!s.empty() && arr[s.peek()] >= arr[i])                s.pop();                  if (!s.empty())                left[i] = s.peek();                  s.push(i);        }              // Empty the stack as stack is// going to be used for right[]        while (!s.empty())            s.pop();              // Fill elements of right[] using same logic        for (int i = n-1 ; i>=0 ; i-- )        {            while (!s.empty() && arr[s.peek()] >= arr[i])                s.pop();                  if(!s.empty())                right[i] = s.peek();                  s.push(i);        }              // Create and initialize answer array        int ans[] = new int[n+1];        for (int i=0; i<=n; i++)            ans[i] = 0;              // Fill answer array by comparing minimums of all        // lengths computed using left[] and right[]        for (int i=0; i<n; i++)        {            // length of the interval            int len = right[i] - left[i] - 1;                  // arr[i] is a possible answer for this length            // 'len' interval, check if arr[i] is more than            // max for 'len'            ans[len] = Math.max(ans[len], arr[i]);        }              // Some entries in ans[] may not be filled yet. Fill        // them by taking values from right side of ans[]        for (int i=n-1; i>=1; i--)            ans[i] = Math.max(ans[i], ans[i+1]);              // Print the result        for (int i=1; i<=n; i++)            System.out.print(ans[i] + " ");    }         // Driver method    public static void main(String[] args)    {        printMaxOfMin(arr.length);    }}
# An efficient Python3 program to find# maximum of all minimums of windows of# different sizes def printMaxOfMin(arr, n):         s = [] # Used to find previous           # and next smaller     # Arrays to store previous and next    # smaller. Initialize elements of    # left[] and right[]    left = [-1] * (n + 1)    right = [n] * (n + 1)     # Fill elements of left[] using logic discussed on    # https:#www.geeksforgeeks.org/next-greater-element    for i in range(n):        while (len(s) != 0 and               arr[s[-1]] >= arr[i]):            s.pop()         if (len(s) != 0):            left[i] = s[-1]         s.append(i)     # Empty the stack as stack is going    # to be used for right[]    while (len(s) != 0):        s.pop()     # Fill elements of right[] using same logic    for i in range(n - 1, -1, -1):        while (len(s) != 0 and arr[s[-1]] >= arr[i]):            s.pop()         if(len(s) != 0):            right[i] = s[-1]         s.append(i)     # Create and initialize answer array    ans = [0] * (n + 1)    for i in range(n + 1):        ans[i] = 0     # Fill answer array by comparing minimums    # of all. Lengths computed using left[]    # and right[]    for i in range(n):                 # Length of the interval        Len = right[i] - left[i] - 1         # arr[i] is a possible answer for this        #  Length 'Len' interval, check if arr[i]        # is more than max for 'Len'        ans[Len] = max(ans[Len], arr[i])     # Some entries in ans[] may not be filled    # yet. Fill them by taking values from    # right side of ans[]    for i in range(n - 1, 0, -1):        ans[i] = max(ans[i], ans[i + 1])     # Print the result    for i in range(1, n + 1):        print(ans[i], end = " ") # Driver Codeif __name__ == '__main__':     arr = [10, 20, 30, 50, 10, 70, 30]    n = len(arr)    printMaxOfMin(arr, n) # This code is contributed by PranchalK
// An efficient C# program to find maximum// of all minimums of windows of different sizeusing System;using System.Collections.Generic; class GFG{public static int[] arr = new int[] {10, 20, 30, 50,                                     10, 70, 30}; public static void printMaxOfMin(int n){    // Used to find previous and next smaller    Stack<int> s = new Stack<int>();     // Arrays to store previous    // and next smaller    int[] left = new int[n + 1];    int[] right = new int[n + 1];     // Initialize elements of left[]    // and right[]    for (int i = 0; i < n; i++)    {        left[i] = -1;        right[i] = n;    }     // Fill elements of left[] using logic discussed on    // https://www.geeksforgeeks.org/next-greater-element/    for (int i = 0; i < n; i++)    {        while (s.Count > 0 &&               arr[s.Peek()] >= arr[i])        {            s.Pop();        }         if (s.Count > 0)        {            left[i] = s.Peek();        }         s.Push(i);    }     // Empty the stack as stack is going    // to be used for right[]    while (s.Count > 0)    {        s.Pop();    }     // Fill elements of right[] using    // same logic    for (int i = n - 1 ; i >= 0 ; i--)    {        while (s.Count > 0 &&               arr[s.Peek()] >= arr[i])        {            s.Pop();        }         if (s.Count > 0)        {            right[i] = s.Peek();        }         s.Push(i);    }     // Create and initialize answer array    int[] ans = new int[n + 1];    for (int i = 0; i <= n; i++)    {        ans[i] = 0;    }     // Fill answer array by comparing    // minimums of all lengths computed    // using left[] and right[]    for (int i = 0; i < n; i++)    {        // length of the interval        int len = right[i] - left[i] - 1;         // arr[i] is a possible answer for        // this length 'len' interval, check x        // if arr[i] is more than max for 'len'        ans[len] = Math.Max(ans[len], arr[i]);    }     // Some entries in ans[] may not be    // filled yet. Fill them by taking    // values from right side of ans[]    for (int i = n - 1; i >= 1; i--)    {        ans[i] = Math.Max(ans[i], ans[i + 1]);    }     // Print the result    for (int i = 1; i <= n; i++)    {        Console.Write(ans[i] + " ");    }} // Driver Codepublic static void Main(string[] args){    printMaxOfMin(arr.Length);}} // This code is contributed by Shrikant13
<script>    // An efficient Javascript program to find maximum    // of all minimums of windows of different size    let arr = [10, 20, 30, 50, 10, 70, 30];    function printMaxOfMin(n)    {             // Used to find previous and next smaller        let s = [];         // Arrays to store previous        // and next smaller        let left = new Array(n + 1);        left.fill(0);        let right = new Array(n + 1);        right.fill(0);         // Initialize elements of left[]        // and right[]        for (let i = 0; i < n; i++)        {            left[i] = -1;            right[i] = n;        }         // Fill elements of left[] using logic discussed on        // https://www.geeksforgeeks.org/next-greater-element/        for (let i = 0; i < n; i++)        {            while (s.length > 0 && arr[s[s.length - 1]] >= arr[i])            {                s.pop();            }             if (s.length > 0)            {                left[i] = s[s.length - 1];            }             s.push(i);        }         // Empty the stack as stack is going        // to be used for right[]        while (s.length > 0)        {            s.pop();        }         // Fill elements of right[] using        // same logic        for (let i = n - 1 ; i >= 0 ; i--)        {            while (s.length > 0 && arr[s[s.length - 1]] >= arr[i])            {                s.pop();            }             if (s.length > 0)            {                right[i] = s[s.length - 1];            }             s.push(i);        }         // Create and initialize answer array        let ans = new Array(n + 1);        ans.fill(0);        for (let i = 0; i <= n; i++)        {            ans[i] = 0;        }         // Fill answer array by comparing        // minimums of all lengths computed        // using left[] and right[]        for (let i = 0; i < n; i++)        {                     // length of the interval            let len = right[i] - left[i] - 1;             // arr[i] is a possible answer for            // this length 'len' interval, check x            // if arr[i] is more than max for 'len'            ans[len] = Math.max(ans[len], arr[i]);        }         // Some entries in ans[] may not be        // filled yet. Fill them by taking        // values from right side of ans[]        for (let i = n - 1; i >= 1; i--)        {            ans[i] = Math.max(ans[i], ans[i + 1]);        }         // Print the result        for (let i = 1; i <= n; i++)        {            document.write(ans[i] + " ");        }    }         printMaxOfMin(arr.length);       // This code is contributed by decode2207.</script>
Output: 
70 30 20 10 10 10 10
Complexity Analysis:  
Time Complexity: O(n). Every sub-task in this approach takes Linear time.
Auxiliary Space : O(n). Use of stack for calculating next minimum and arrays to store the intermediate results.
This article is contributed by Ekta Goel and Ayush Govil. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Sam007
nitin mittal
shrikanth13
sahilshelangia
sanskar27jain
PranchalKatiyar
nidhi_biet
bidibaaz123
brashcaran
aashish1995
decode2207
simranarora5sos
Amazon
sliding-window
Stack
Amazon
sliding-window
Stack
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Implement Stack using Queues
Iterative Depth First Traversal of Graph
Merge Overlapping Intervals
Reverse a stack using recursion
Largest Rectangular Area in a Histogram | Set 2
Difference between Stack and Queue Data Structures
The Stock Span Problem
Design and Implement Special Stack Data Structure | Added Space Optimized Version
Sort a stack using recursion
Iterative Postorder Traversal | Set 2 (Using One Stack)