84.柱状图中最大的矩形
只有栈里从大到小的顺序,才能保证栈顶元素找到左右两边第一个小于栈顶元素的柱子。
所以本题单调栈的顺序正好与接雨水反过来。
此时大家应该可以发现其实就是栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度
理解这一点,对单调栈就掌握的比较到位了。
除了栈内元素顺序和接雨水不同,剩下的逻辑就都差不多了,在题解42. 接雨水 (opens new window)我已经对单调栈的各个方面做了详细讲解,这里就不赘述了。
剩下就是分析清楚如下三种情况:
- 情况一:当前遍历的元素heights[i]小于栈顶元素heights[st.top()]的情况
- 情况二:当前遍历的元素heights[i]等于栈顶元素heights[st.top()]的情况
- 情况三:当前遍历的元素heights[i]大于栈顶元素heights[st.top()]的情况
-
class Solution { public int largestRectangleArea(int[] heights) { int length = heights.length; int[] minLeftIndex = new int [length]; int[] maxRigthIndex = new int [length]; // 记录左边第一个小于该柱子的下标 minLeftIndex[0] = -1 ; for (int i = 1; i < length; i++) { int t = i - 1; // 这里不是用if,而是不断向右寻找的过程 while (t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t]; minLeftIndex[i] = t; } // 记录每个柱子 右边第一个小于该柱子的下标 maxRigthIndex[length - 1] = length; for (int i = length - 2; i >= 0; i--) { int t = i + 1; while(t < length && heights[t] >= heights[i]) t = maxRigthIndex[t]; maxRigthIndex[i] = t; } // 求和 int result = 0; for (int i = 0; i < length; i++) { int sum = heights[i] * (maxRigthIndex[i] - minLeftIndex[i] - 1); result = Math.max(sum, result); } return result; } }