目录
84.柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求
在该柱状图中,能够勾勒出来的矩形的最大面积。
看到题目时的第一想法
想到用单调栈,但是不知道怎么做
看到代码随想录的想法
单调栈,单调减,若遇到比栈顶小的元素则出栈
以栈顶为基准来算最大面积,找左边第一个比自己小的下标,遍历过的元素,栈顶第二个元素
找右边第一个比自己小的下标,当前遍历到的元素(若比栈顶小)
两者下标之差值-1,就是宽度,当前栈顶就是高度
实现时出现的困难
开始没理解怎么找左右比当前小的元素,其实只要把当前元素当成栈顶元素,就很好区分了(之前把遍历到的元素当成当前元素了)
计算面积时,用栈顶元素当成高,左右下标的差值-1当成宽度,来计算
class Solution {
public int largestRectangleArea(int[] heights) {
//遇到一个较大的,往前计算?
//单调栈之前是怎么做的
//遇到第一个比自己大的,元素,。
//遇到第一个比自己小的来计算?
//因为它是计算最大面积,是从最小下标开始看大小的
//单调栈:遇到第一个比当前元素大的然后弹出?逐个计算?
//逐个计算
//卡哥思路,单调栈,不过是单调递减,当我们遇到左边第一个比它小的元素和右边第一个比它小的元素,计算矩形的面积
//如何记录下标呢,栈里存下标,然后获取
//当前元素为栈顶元素,当遇到第一个比栈顶元素小的,开始回收面积
//遇到的第一个比栈顶元素小的,为右边第一个比它小的元素,左边第一个比它小的元素为,栈顶第二个元素
Stack<Integer> stack = new Stack<>();
//使用一个新数组,左右补0
//为什么要补0?若为递减的数组,永远找不到第一个比栈顶小的元素,所以要在最后补0
//前面补0,考虑第一个元素,要找到左边比它小的,所以需要补个0
int[] newHeights = new int[heights.length+2];
newHeights[0] = 0;
newHeights[heights.length+1]=0;
for(int i=0;i<heights.length;i++){
newHeights[i+1] = heights[i];
}
stack.push(0);
int result = 0;
for(int i=1;i<newHeights.length;i++){
//若当前元素比栈顶的要大直接入栈
if(newHeights[i]>=newHeights[stack.peek()]){
stack.push(i);
}else{
while(!stack.isEmpty()&&newHeights[i]<newHeights[stack.peek()]){
//当前元素
int item = stack.pop();
//找到了左边比它小的和右边比它小的,要怎么计算呢
//左边比它小的下标-右边比它小的下标-1
if(!stack.isEmpty()){
//right 应该为i
int right = i;
//left 应该为peek
int left = stack.peek();
result = Math.max((right-left-1)*newHeights[item],result);
}
}
stack.push(i);
}
}
return result;
}
}