一、理论基础
- 通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。时间复杂度为O(n)。
- 单调栈的本质是空间换时间,就是用一个栈来记录我们遍历过的元素
- 单调栈加入的元素是数组的下标
二、每日温度
-
题目
- 给定一个整数数组
temperatures
,表示每天的温度,返回一个数组answer
,其中answer[i]
是指对于第i
天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用0
来代替。
- 给定一个整数数组
-
思路
- 当前遍历元素大于栈顶元素,表示栈顶元素右边第一个大元素是当前元素,弹出栈顶并记录。
-
代码
class Solution { public int[] dailyTemperatures(int[] temperatures) { int[] res = new int[temperatures.length]; Deque<Integer> deque = new LinkedList<>(); for (int i = 0; i < temperatures.length; i++) { while (!deque.isEmpty() && temperatures[i] > temperatures[deque.peek()]) { int index = deque.pop(); res[index] = i - index; } deque.push(i); } return res; } }
三、下一个更大元素
-
题目
-
思路
- 对nums2进行处理成单调栈{},并用map记录<值,下一个更大元素的值>
-
代码
class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Deque<Integer> deque = new LinkedList<>(); Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums2.length; i++) { while (!deque.isEmpty() && deque.peek() < nums2[i]) { map.put(deque.pop(), nums2[i]); } deque.push(nums2[i]); } for (int i = 0; i < nums1.length; i++) { nums1[i] = map.getOrDefault(nums1[i], -1); } return nums1; } }
四、下一个更大元素II
-
题目
-
思路
- 执行两次
-
代码
class Solution { public int[] nextGreaterElements(int[] nums) { int[] res = new int[nums.length]; Arrays.fill(res, -1); Deque<Integer> deque = new LinkedList<>(); for (int i = 0; i < 2 * nums.length; i++) { while (!deque.isEmpty() && nums[deque.peek()] < nums[i % nums.length]) { res[deque.pop()] = nums[i % nums.length]; } deque.push(i % nums.length); } return res; } }
五、接雨水
-
题目
- 给定
n
个非负整数表示每个宽度为1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
- 给定
-
思路
- 维护大到小单调栈
-
代码
class Solution { public int trap(int[] height) { Deque<Integer> deque = new LinkedList<>(); int res = 0; for (int i = 0; i < height.length; i++) { while (!deque.isEmpty() && height[deque.peek()] < height[i]) { int mid = height[deque.pop()]; if (!deque.isEmpty()) { res += (Math.min(height[i], height[deque.peek()]) - mid) * (i - deque.peek() - 1); } } deque.push(i); } return res; } }
六、柱状图中最大的矩形
-
题目
-
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。
-
-
思路
- 维护小到大单调栈
-
代码
class Solution { public int largestRectangleArea(int[] heights) { Deque<Integer> deque = new LinkedList<>(); int[] temp = new int[heights.length + 2]; temp[temp.length - 1] = 0; for (int i = 0; i < heights.length; i++) { temp[i + 1] = heights[i]; } int res = 0; for (int i = 0; i < temp.length; i++) { while (!deque.isEmpty() && temp[deque.peek()] > temp[i]) { int mid = deque.pop(); res = Math.max(res, temp[mid] * (i - deque.peek() - 1)); } deque.push(i); } return res; } }