代码随想录一刷last day|84.柱状图中最大的矩形

84.柱状图中最大的矩形

这道题和接雨水那道题是遥相呼应的

因为,接雨水那道题需要找某一列左右两边第一个高于该列的,而本题要找某一列左右两边第一个低于该列的,正好相反。因此我们的单调栈从栈头到栈底应该是从大到小的(从栈头弹出元素)。

此时大家应该可以发现其实就是栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度

分3种情况:

1.当前元素大于栈头元素,直接push

2.当前元素等于栈头元素,直接push

3.当前元素小于栈头元素,计算出面积然后再push当前元素

注意在这题中,我们需要在height数组的头部和尾部分别加上数字0;

在头部加上0的目的是为了防止height数组是降序数组的时候如[8,4,3,2]

在尾部加上0的目的是为了防止height数组是升序数组的时候如[2,3,4,8]

代码实现

在这里我开始不太明白为什么是 int h=newHeights[mid];

后来想明白:每次我们只会弹出一个元素即mid来计算,因此参与面积计算的就是当前遍历到的柱形和被弹出的柱形,所以要以被弹出的柱形的高度作为面积的高,如果满足st非空且当前元素小于栈头元素,那么会一直弹出栈里的元素

class Solution {
    public int largestRectangleArea(int[] heights) {
        Stack<Integer> st = new Stack<Integer>();
        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];
        }

        
        st.push(0);
        int result=0;
        for(int i=1;i<newHeights.length;i++){
            if(newHeights[i]>=newHeights[st.peek()]){//当前元素大于栈头元素,直接push
            st.push(i);

            }
            // else if(newHeights[i]==st.peek()){//当前元素等于栈头元素,直接push

            // }
            else{//当前元素小于栈头元素,计算出面积然后再push当前元素
            while(!st.isEmpty()&&newHeights[i]<newHeights[st.peek()]){
                int mid=st.pop();
                int left=st.peek();
                // int h=Math.min(left,i);//h=Math.min(left,i);还是int h=heights[mid];
                
                int h=newHeights[mid];//注意这里是int h=heights[mid];每次我们只会弹出一个元素即mid来计算,因此参与面积计算的就是当前遍历到的柱形和被弹出的柱形,所以要以被弹出的柱形的高度作为面积的高,如果满足st非空且当前元素小于栈头元素,那么会一直弹出栈里的元素
                int w=i-left-1;   
                result=Math.max(result,w*h);
                System.out.println(result);
                }

            }
            st.push(i);//这次计算完当前的最大面积后要将这次到达的下标入栈,方便下一次计算


            }
         return result;
        }
      
}

接下来先总结回顾再准备二刷时间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值