Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer array arr[] of size N, find the maximum of the minimums for every window size in the given array. 
Note: The window size varies from 1 to N.

Example:

Input: arr[] = {10, 20, 30, 50, 10, 70, 30} 
Output: 70, 30, 20, 10, 10, 10, 10
Explanation:
The 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 70
The 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 30
The 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 20
Similarly, other elements of output are computed. 

Finding the Maximum of Minimums for every window size by Brute-force method:

The idea is to calculate the minimum of every window separately and print the maximum of each window size.

Follow the steps below to implement the above idea:

  • Traverse a loop on K from1 till N
    • Initialize a variable maxOfMin = INT_MIN
    • Initialize a nested on i loop from 0 till N – K
    • Initialize a variable min = arr[i]
      • Initialize another nested loop on j from 1 till K
        • If min > arr[i + j]
          • Update min = arr[i + j]
      • If maxOfMin < min
        • Update maxOfMin = min
    • Print maxOfMin for the window of size K.

Below is the implementation of the above approach:

C++




// 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 program
int main()
{
    int arr[] = { 10, 20, 30, 50, 10, 70, 30 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printMaxOfMin(arr, n);
    return 0;
}


Java




// 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);
    }
}


Python3




# A naive method to find maximum of
# minimum of all windows of different sizes
INT_MIN = -1000000
 
 
def 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 Code
arr = [10, 20, 30, 50, 10, 70, 30]
n = len(arr)
printMaxOfMin(arr, n)
 
# This code is contributed by sahilshelangia


C#




// C# program using Naive approach to find
// maximum of minimum of all windows of
// different sizes
using 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
// PHP program to find maximum of
// minimum of all windows of
// different sizes
 
// Method to find maximum of
// minimum of all windows of
// different sizes
function 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.
?>


Javascript




<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 

Time Complexity: O(N3), where N is the size of the given array.
Auxiliary Space: O(1), constant extra space is being used.

Finding the Maximum of Minimums for every window size by using Stack:

The idea is to find the next smaller and previous smaller of each element and update the maximum of window with size as the difference in their indices.

Follow the steps below to implement the above idea:

  • Initialize a stack s.
  • Create two arrays, left and right of size N + 1 to store the next smaller and the previous smaller elements.
  • Traverse a loop on i from 0 till N
    • Assign left[i] = -1 and right[i] = N
  • Traverse a loop on i from 0 till N
    • Pop the elements from s while the current element is not greater than the element at top of stack s.
    • If the stack is not empty
      • Update left[i] = s.top()
    • Push current index in stack s
  • Empty the stack s.
  • Traverse a loop on i from N – 1 till 0
    • Pop the elements from s while the current element is not greater than the element at top of stack s.
    • If the stack is not empty
      • Update right[i] = s.top()
    • Push current index in stack s
  • Initialize an array ans of size N + 1 with 0.
  • Traverse a loop on i from 0 till N
    • Initialize len = left[i] – right[i] + 1
    • Update ans[len] = max(ans[len], arr[i])
  • Traverse a loop on i from N – 1 till 0
    • Update ans[i] = max(ans[i], ans[i + 1])
  • Print ans array. 

Below is the implementation of the above approach:

C++




// 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
    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 program
int main()
{
    int arr[] = { 10, 20, 30, 50, 10, 70, 30 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printMaxOfMin(arr, n);
    return 0;
}


Java




// 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
        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);
    }
}


Python3




# 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 Code
if __name__ == '__main__':
 
    arr = [10, 20, 30, 50, 10, 70, 30]
    n = len(arr)
    printMaxOfMin(arr, n)
 
# This code is contributed by PranchalK


C#




// An efficient C# program to find maximum
// of all minimums of windows of different size
using 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
        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 Code
    public static void Main(string[] args)
    {
        printMaxOfMin(arr.Length);
    }
}
 
// This code is contributed by Shrikant13


Javascript




<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
        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 

Time Complexity: O(N), where N is the size of the given array.
Auxiliary Space: O(N), for using stack and additional arrays.



Last Updated : 02 Nov, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads