题目
思路
根据官方题解,这道题的思路为:
分别以每个柱子为高,往左右延伸,看能延伸多远,作为宽,将高 * 宽记为area
当所有柱子都计算完后,返回最大的那个area
然后用单调栈优化,快速找到左右两边最近比当前柱子小的是哪个
但问题是:为什么这样做是对的?
首先需要明确:所有可能成为最大矩形的矩形,其高一定等于这个矩形覆盖的柱子中,最矮的那个
为什么?用反证法
- 假设比最矮的那个还矮,那必然不是最大的矩形,因为高度可以更高
- 假设比最矮的那个更高,这不可能
那我们可以遍历每一个柱子,计算以当前柱子为最矮的情况下(即高度为当前柱子),宽度能有多宽
因为最大的那个矩形,其高度必然等于其中一个柱子
而我们将以每个柱子为高,的最大面积都计算出来了,因此答案必在其中!
代码
代码其实没太多好讲的,标准的单调栈做法:
public int largestRectangleArea(int[] heights) {
Stack<Integer> stack = new Stack<>();
stack.push(-1);
int maxArea = 0;
for (int i = 0;i< heights.length;i++) {
while (stack.peek() != -1 && heights[i] < heights[stack.peek()]) {
int height = heights[stack.peek()];
stack.pop();
int width = i - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
while (stack.peek() != -1) {
int height = heights[stack.peek()];
stack.pop();
int width = heights.length - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
return maxArea;
}