LeetCode(cai鸟之路)84. 柱状图中最大的矩形

题目描述

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例

在这里插入图片描述
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

代码1(超时了,但是算法思路是对的):

public class Solution84 {
  
    public static int largestRectangleArea(int[] heights) {

        int maxElem = 0;
        for (int height : heights) {
            if (height >= maxElem){
                maxElem = height;
            }
        }
        int[] cutHeight = new int[heights.length];
        int area_max = 0;
        int index = 0;
        for (int i = 0;i<maxElem;i++){
            int len = 0;
            int min = Integer.MAX_VALUE;
            for (int j = 0;j<heights.length;j++){
                cutHeight[j] = (heights[j]-(i))<0?0:heights[j]-(i);
                if ( cutHeight[j]== 0){
                    len = 0;
                    min = Integer.MAX_VALUE;
                }else {
                    len++;
                    if (cutHeight[j]<=min){
                        min = cutHeight[j];
                        index = j;
                    }
                    int tempArea =  (len)*heights[index];
                    if (tempArea>=area_max){
                        area_max = tempArea;
                    }
                }
            }
        }
        return area_max;
    }

}

代码2(单调递增栈):

class Solution {
   public int largestRectangleArea(int[] heights) {
        // 初始化最终结果为0
        int res = 0;
        Stack<Integer> stack = new Stack<>();
        // 将给定的原数组左右各添加一个元素0
        int[] newHeights = new int[heights.length + 2];
        newHeights[0] = 0;
        newHeights[newHeights.length-1] = 0;
        for (int i = 1; i < heights.length + 1; i++) {
            newHeights[i] = heights[i - 1];
        }
        // 开始遍历
        for (int i = 0; i < newHeights.length; i++) {
            // 如果栈不为空且当前考察的元素值小于栈顶元素值,
            // 则表示以栈顶元素值为高的矩形面积可以确定
            while (!stack.isEmpty() && newHeights[i] < newHeights[stack.peek()]) {
                // 弹出栈顶元素
                int cur = stack.pop();
                // 获取栈顶元素对应的高
                int curHeight = newHeights[cur];

                // 栈顶元素弹出后,新的栈顶元素就是其左侧边界
                int leftIndex = stack.peek();
                // 右侧边界是当前考察的索引
                int rightIndex = i;
                // 计算矩形宽度
                int curWidth = rightIndex - leftIndex - 1;

                // 计算面积
                res = Math.max(res, curWidth * curHeight);
            }
            
            // 当前考察索引入栈
            stack.push(i);
        }
        return res;
    }
}

分析

代码一所有的方法比较奇特,是一行一行减1之后,寻找连续非零的长度,然后再非零中找出最小的下标值,然后进行求解,由于代码一的代码比较复杂,以及变量也比较多,所以时间复杂度超了,但是可以参考一下本方法的思想。
在这里插入图片描述
代码二使用单调递增栈进行求解,和之前的接雨水那题比较相似,但是那题是单调递减栈,本题是单调递增栈,就是当前元素如果小于栈顶元素,就将栈顶元素出栈,知道遇到栈顶元素小于当前元素即可。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/largest-rectangle-in-histogram/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值