|
| 1 | +package DataStructures.Stacks; |
| 2 | + |
| 3 | +import java.util.Arrays; |
| 4 | +import java.util.Stack; |
| 5 | + |
| 6 | +/** |
| 7 | + * Given an integer array. The task is to find the maximum of the minimum of every window size in the array. |
| 8 | + * Note: Window size varies from 1 to the size of the Array. |
| 9 | + * <p> |
| 10 | + * For example, |
| 11 | + * <p> |
| 12 | + * N = 7 |
| 13 | + * arr[] = {10,20,30,50,10,70,30} |
| 14 | + * <p> |
| 15 | + * So the answer for the above would be : 70 30 20 10 10 10 10 |
| 16 | + * <p> |
| 17 | + * We need to consider window sizes from 1 to length of array in each iteration. |
| 18 | + * So in the iteration 1 the windows would be [10], [20], [30], [50], [10], [70], [30]. |
| 19 | + * Now we need to check the minimum value in each window. Since the window size is 1 here the minimum element would be the number itself. |
| 20 | + * Now the maximum out of these is the result in iteration 1. |
| 21 | + * In the second iteration we need to consider window size 2, so there would be [10,20], [20,30], [30,50], [50,10], [10,70], [70,30]. |
| 22 | + * Now the minimum of each window size would be [10,20,30,10,10] and the maximum out of these is 30. |
| 23 | + * Similarly we solve for other window sizes. |
| 24 | + * |
| 25 | + * @author sahil |
| 26 | + */ |
| 27 | +public class MaximumMinimumWindow { |
| 28 | + |
| 29 | + /** |
| 30 | + * This function contains the logic of finding maximum of minimum for every window size |
| 31 | + * using Stack Data Structure. |
| 32 | + * |
| 33 | + * @param arr Array containing the numbers |
| 34 | + * @param n Length of the array |
| 35 | + * @return result array |
| 36 | + */ |
| 37 | + public static int[] calculateMaxOfMin(int[] arr, int n) { |
| 38 | + Stack<Integer> s = new Stack<>(); |
| 39 | + int left[] = new int[n + 1]; |
| 40 | + int right[] = new int[n + 1]; |
| 41 | + for (int i = 0; i < n; i++) { |
| 42 | + left[i] = -1; |
| 43 | + right[i] = n; |
| 44 | + } |
| 45 | + |
| 46 | + for (int i = 0; i < n; i++) { |
| 47 | + while (!s.empty() && arr[s.peek()] >= arr[i]) |
| 48 | + s.pop(); |
| 49 | + |
| 50 | + if (!s.empty()) |
| 51 | + left[i] = s.peek(); |
| 52 | + |
| 53 | + s.push(i); |
| 54 | + } |
| 55 | + |
| 56 | + while (!s.empty()) |
| 57 | + s.pop(); |
| 58 | + |
| 59 | + for (int i = n - 1; i >= 0; i--) { |
| 60 | + while (!s.empty() && arr[s.peek()] >= arr[i]) |
| 61 | + s.pop(); |
| 62 | + |
| 63 | + if (!s.empty()) |
| 64 | + right[i] = s.peek(); |
| 65 | + |
| 66 | + s.push(i); |
| 67 | + } |
| 68 | + |
| 69 | + int ans[] = new int[n + 1]; |
| 70 | + for (int i = 0; i <= n; i++) |
| 71 | + ans[i] = 0; |
| 72 | + |
| 73 | + for (int i = 0; i < n; i++) { |
| 74 | + int len = right[i] - left[i] - 1; |
| 75 | + |
| 76 | + ans[len] = Math.max(ans[len], arr[i]); |
| 77 | + } |
| 78 | + |
| 79 | + for (int i = n - 1; i >= 1; i--) |
| 80 | + ans[i] = Math.max(ans[i], ans[i + 1]); |
| 81 | + |
| 82 | + // Print the result |
| 83 | + for (int i = 1; i <= n; i++) |
| 84 | + System.out.print(ans[i] + " "); |
| 85 | + return ans; |
| 86 | + } |
| 87 | + |
| 88 | + public static void main(String args[]) { |
| 89 | + int[] arr = new int[]{10, 20, 30, 50, 10, 70, 30}; |
| 90 | + int[] target = new int[]{70, 30, 20, 10, 10, 10, 10}; |
| 91 | + int[] res = calculateMaxOfMin(arr, arr.length); |
| 92 | + assert Arrays.equals(target, res); |
| 93 | + } |
| 94 | + |
| 95 | +} |
0 commit comments