84.柱状图中最大的矩形
思路:本题十分适合与接雨水对照来看,接雨水其实是找每个柱子两边第一个大于该柱子高度的柱子,而本题的实质是找每个柱子左右两边第一个小于该柱子的柱子。
本题与接雨水最主要的区别在于单调栈中存放元素的顺序不同。其他步骤与接雨水的分析过程相同。注意代码细节和逻辑。(栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度)
class Solution {
public int largestRectangleArea(int[] heights) { // 找每个柱子左右两边第一个小于该柱子的柱子
int res = 0;
Deque<Integer> stack = new LinkedList<>();
stack.push(0);
// 数组前后加一个0
int[] newHeights = new int[heights.length + 2];
newHeights[0] = 0;
newHeights[newHeights.length - 1] = 0;
for (int i = 0; i < heights.length; i++) {
newHeights[i + 1] = heights[i];
}
// 开始遍历
for (int i = 1; i < newHeights.length; i++) {
if (newHeights[i] > newHeights[stack.peek()]) {
stack.push(i);
} else if (newHeights[i] == newHeights[stack.peek()]) {
stack.pop(); // 有没有效果一样
stack.push(i);
} else {
while (!stack.isEmpty() && newHeights[i] < newHeights[stack.peek()]) {
int mid = stack.pop();
if (!stack.isEmpty()) {
int left = stack.peek();
int h = newHeights[mid];
int w = i - left - 1;
res = Math.max(res, h * w);
}
}
stack.push(i);
}
}
return res;
}
}