题目
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4]
输出: 4
题解
class Solution {
public int largestRectangleArea(int[] heights) {
int res=0;
Deque<Integer> stack=new ArrayDeque<>();//ArrayDeque!
int[] newHeights=new int[heights.length+2];
for(int i=0;i<heights.length;i++){
newHeights[i+1]=heights[i];
}//数组前后补0
for(int i=0;i<newHeights.length;i++){
while(!stack.isEmpty()&&newHeights[i]<newHeights[stack.peek()]){
//栈顶元素大于当前遍历到的元素,则第i根柱子为最矮柱子所能延伸的最大面积可求得
int h=stack.pop();//h是index...
res=Math.max(res,(i-stack.peek()-1)*newHeights[h]);
}
stack.push(i);
}
return res;
}
}
笔记:
-
在一维数组中对每一个数找到第一个比自己小的元素。这类“在一维数组中找第一个满足某种条件的数”的场景就是典型的单调栈应用场景。
-
下一个柱形的高度大,则矩形还不能确定,入栈。
-
在记录哪些柱子是暂时不能确定以其高为矩形的面积时,是从左到右放入记录列表的;当可以确定以其高为矩形的面积时,是从右到左移除列表的。这个特性符合栈的性质吗,先进后出,后进先出。
-
思路:遍历每个柱体i,分别找到其左边和右边第一个小于i的柱体,则其对应的矩形面积为 i的高度*两个小柱体之间夹的宽度,求出最终的最大面积(以第i根柱子为最矮柱子所能延伸的最大面积)。
-
暴力方法是对每个柱体左右的较矮柱体进行遍历,优化方法是使用栈。
-
当然为了避免到了最后一直都是递增的,所以可以在最后加一块高度为0的木板。