题意理解:
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
这道题目和接雨水的题目类似,接雨水的题目求柱子外组成得到部分,而这道题求解的是柱子内组成的部分。
对于这道题,我们呢选中一个柱子,高度h,进行扩展,左边第一个比它小的元素下标是i, 右边第一个比它小的元素下标为j, 则矩形的宽度为:w=j-i-1
则选中的矩形可得到的最大高度为: S=h*w=h*(j-i-1)
解题思路:
(1) 定义单调栈,总是查找右边第一个比它小的元素,所以保证栈单调递减,栈口总是压入比栈顶大的值
(2) 面积计算
S=h*w=h*(j-i-1)=height[i]*(j-1-1)
(3) 设置maxS,获取最大的S面积
特别的:
如: 8、6、4 第二个元素进入时,出发计算,但目前只有两个元素,没有最右边的边界,所以,在整个数组前面添加一个0,来辅助计算
如:4、6、8 全部元素进入,没有比它小的元素来出发计算,所以,最整个数组后面添加一个0,来辅助计算。
1.单调栈解题
public int largestRectangleArea(int[] heights) {
int result=0;
int[] newHeight=new int[heights.length+2];
newHeight[0]=0;
newHeight[heights.length+1]=0;
for(int i=0;i<heights.length;i++){
newHeight[i+1]=heights[i];
}
Stack<Integer> stack=new Stack<>();
stack.push(0);
for(int i=1;i<newHeight.length;i++){
if(newHeight[i]>=newHeight[stack.peek()]){
stack.push(i);
}else{
while((!stack.isEmpty())&&newHeight[i]<newHeight[stack.peek()]){
int S=newHeight[stack.pop()]*(i-stack.peek()-1);
result=Math.max(result,S);
}
stack.push(i);
}
}
return result;
}
2.复杂度分析
时间复杂度:O(n)
空间复杂度:O(n)