|
| 1 | +import java.util.Stack; |
| 2 | + |
| 3 | +/** |
| 4 | + * This utility provides commonly used operations related to stacks, which can be beneficial for solving various problems such as expression evaluations, balanced parentheses, or maintaining a history of operations |
| 5 | + * MinStack: This custom stack keeps track of the minimum element so that getMin() can return the minimum in O(1) time. |
| 6 | + * Next Greater Element: For each element in an array, the utility finds the next greater element on the right side using a stack. |
| 7 | + * Balanced Parentheses Checker: It checks if an expression has matching and balanced parentheses. |
| 8 | + * Reverse a Stack: This utility reverses the elements in a stack using recursion. |
| 9 | + * @author Mohit Singh |
| 10 | + * @author <a href="https://github.com/mohit-gogitter">mohit-gogitter<a> |
| 11 | + */ |
| 12 | + |
| 13 | +public class Main { |
| 14 | + |
| 15 | + // 1. MinStack - Stack supporting push, pop, and retrieving minimum in O(1) time |
| 16 | + static class MinStack { |
| 17 | + private Stack<Integer> mainStack; |
| 18 | + private Stack<Integer> minStack; |
| 19 | + |
| 20 | + public MinStack() { |
| 21 | + mainStack = new Stack<>(); |
| 22 | + minStack = new Stack<>(); |
| 23 | + } |
| 24 | + |
| 25 | + public void push(int value) { |
| 26 | + mainStack.push(value); |
| 27 | + if (minStack.isEmpty() || value <= minStack.peek()) { |
| 28 | + minStack.push(value); |
| 29 | + } |
| 30 | + } |
| 31 | + |
| 32 | + public void pop() { |
| 33 | + if (!mainStack.isEmpty()) { |
| 34 | + int poppedValue = mainStack.pop(); |
| 35 | + if (poppedValue == minStack.peek()) { |
| 36 | + minStack.pop(); |
| 37 | + } |
| 38 | + } |
| 39 | + } |
| 40 | + |
| 41 | + public int getMin() { |
| 42 | + return minStack.isEmpty() ? Integer.MAX_VALUE : minStack.peek(); |
| 43 | + } |
| 44 | + |
| 45 | + public int top() { |
| 46 | + return mainStack.isEmpty() ? -1 : mainStack.peek(); |
| 47 | + } |
| 48 | + |
| 49 | + public boolean isEmpty() { |
| 50 | + return mainStack.isEmpty(); |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + // 2. Next Greater Element for each element in an array |
| 55 | + public static int[] nextGreaterElement(int[] nums) { |
| 56 | + Stack<Integer> stack = new Stack<>(); |
| 57 | + int[] result = new int[nums.length]; |
| 58 | + |
| 59 | + for (int i = nums.length - 1; i >= 0; i--) { |
| 60 | + while (!stack.isEmpty() && stack.peek() <= nums[i]) { |
| 61 | + stack.pop(); |
| 62 | + } |
| 63 | + result[i] = stack.isEmpty() ? -1 : stack.peek(); |
| 64 | + stack.push(nums[i]); |
| 65 | + } |
| 66 | + return result; |
| 67 | + } |
| 68 | + |
| 69 | + // 3. Balanced Parentheses Checker |
| 70 | + public static boolean isBalanced(String expression) { |
| 71 | + Stack<Character> stack = new Stack<>(); |
| 72 | + for (char c : expression.toCharArray()) { |
| 73 | + if (c == '(' || c == '{' || c == '[') { |
| 74 | + stack.push(c); |
| 75 | + } else if (c == ')' || c == '}' || c == ']') { |
| 76 | + if (stack.isEmpty()) |
| 77 | + return false; |
| 78 | + char open = stack.pop(); |
| 79 | + if (!isMatchingPair(open, c)) |
| 80 | + return false; |
| 81 | + } |
| 82 | + } |
| 83 | + return stack.isEmpty(); |
| 84 | + } |
| 85 | + |
| 86 | + private static boolean isMatchingPair(char open, char close) { |
| 87 | + return (open == '(' && close == ')') || |
| 88 | + (open == '{' && close == '}') || |
| 89 | + (open == '[' && close == ']'); |
| 90 | + } |
| 91 | + |
| 92 | + // 4. Reverse a Stack |
| 93 | + public static <T> void reverseStack(Stack<T> stack) { |
| 94 | + if (stack.isEmpty()) |
| 95 | + return; |
| 96 | + T temp = stack.pop(); |
| 97 | + reverseStack(stack); |
| 98 | + insertAtBottom(stack, temp); |
| 99 | + } |
| 100 | + |
| 101 | + private static <T> void insertAtBottom(Stack<T> stack, T value) { |
| 102 | + if (stack.isEmpty()) { |
| 103 | + stack.push(value); |
| 104 | + } else { |
| 105 | + T temp = stack.pop(); |
| 106 | + insertAtBottom(stack, value); |
| 107 | + stack.push(temp); |
| 108 | + } |
| 109 | + } |
| 110 | + |
| 111 | + public static void main(String[] args) { |
| 112 | + // Example usage of MinStack |
| 113 | + MinStack minStack = new MinStack(); |
| 114 | + minStack.push(3); |
| 115 | + minStack.push(5); |
| 116 | + minStack.push(2); |
| 117 | + minStack.push(1); |
| 118 | + System.out.println("Current Min: " + minStack.getMin()); // Output: 1 |
| 119 | + minStack.pop(); |
| 120 | + System.out.println("Current Min after pop: " + minStack.getMin()); // Output: 2 |
| 121 | + |
| 122 | + // Example usage of nextGreaterElement |
| 123 | + int[] nums = { 4, 5, 2, 10, 8 }; |
| 124 | + int[] nextGreater = nextGreaterElement(nums); |
| 125 | + System.out.println("Next Greater Elements: "); |
| 126 | + for (int val : nextGreater) { |
| 127 | + System.out.print(val + " "); |
| 128 | + } // Output: 5 10 10 -1 -1 |
| 129 | + |
| 130 | + // Example usage of isBalanced |
| 131 | + String expr = "{[()]}"; |
| 132 | + System.out.println("\nIs the expression balanced? " + isBalanced(expr)); // Output: true |
| 133 | + |
| 134 | + // Example usage of reverseStack |
| 135 | + Stack<Integer> stack = new Stack<>(); |
| 136 | + stack.push(1); |
| 137 | + stack.push(2); |
| 138 | + stack.push(3); |
| 139 | + reverseStack(stack); |
| 140 | + System.out.println("Reversed Stack: " + stack); // Output: [3, 2, 1] |
| 141 | + } |
| 142 | +} |
0 commit comments