单调栈数据结构
单调栈的基本概念
单调栈是一种特殊的栈结构,保证栈内元素始终按照单调递增或递减的顺序排列。常用于解决下一个更大元素、下一个更小元素、柱状图最大矩形面积等问题。
单调递增栈的实现(Java)
以下代码实现一个单调递增栈,用于找到数组中每个元素的下一个更大元素(右侧第一个比当前元素大的值):
import java.util.Stack;public class MonotonicStack {public static int[] nextGreaterElement(int[] nums) {int[] result = new int[nums.length];Stack<Integer> stack = new Stack<>();for (int i = nums.length - 1; i >= 0; i--) {// 弹出栈顶比当前元素小的元素while (!stack.isEmpty() && stack.peek() <= nums[i]) {stack.pop();}// 栈顶即为下一个更大元素(若栈为空则无更大元素)result[i] = stack.isEmpty() ? -1 : stack.peek();stack.push(nums[i]);}return result;}public static void main(String[] args) {int[] nums = {2, 1, 2, 4, 3};int[] res = nextGreaterElement(nums);for (int num : res) {System.out.print(num + " "); // 输出: 4 2 4 -1 -1}}
}
单调递减栈的实现(Java)
以下代码实现一个单调递减栈,用于找到数组中每个元素的下一个更小元素(右侧第一个比当前元素小的值):
import java.util.Stack;public class MonotonicStack {public static int[] nextSmallerElement(int[] nums) {int[] result = new int[nums.length];Stack<Integer> stack = new Stack<>();for (int i = nums.length - 1; i >= 0; i--) {// 弹出栈顶比当前元素大的元素while (!stack.isEmpty() && stack.peek() >= nums[i]) {stack.pop();}// 栈顶即为下一个更小元素(若栈为空则无更小元素)result[i] = stack.isEmpty() ? -1 : stack.peek();stack.push(nums[i]);}return result;}public static void main(String[] args) {int[] nums = {2, 1, 2, 4, 3};int[] res = nextSmallerElement(nums);for (int num : res) {System.out.print(num + " "); // 输出: 1 -1 1 3 -1}}
}
关键点说明
方向选择:
- 正向遍历(从左到右):通常用于解决左侧最近更大/更小元素问题。
- 反向遍历(从右到左):通常用于解决右侧最近更大/更小元素问题。
单调性维护:
- 递增栈:通过弹出比当前元素小的值,保证栈顶是第一个更大元素。
- 递减栈:通过弹出比当前元素大的值,保证栈顶是第一个更小元素。
时间复杂度:O(n),每个元素最多入栈和出栈一次。
典型应用场景
- 下一个更大元素(LeetCode 496)。
- 每日温度(LeetCode 739)。
- 柱状图中最大矩形(LeetCode 84)。
- 接雨水问题(LeetCode 42)。