Find maximum of minimum for every window size in a given array
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 min > arr[i + j]
- If maxOfMin < min
- Update maxOfMin = min
- Initialize another nested loop on j from 1 till K
- 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> |
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> |
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.
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.
Please Login to comment...