LeetCode 84.柱状图中最大的矩形

本文详细介绍了如何通过栈优化算法,将寻找柱状图中最大矩形面积的问题从O(n²)的时间复杂度降低到O(n)。通过维护一个高度索引栈,动态计算每个柱子能构成的最大矩形面积,并更新最大结果。代码配合注释清晰地展示了整个过程,适合学习数据结构与算法的读者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

思路:

  • 首先可以想到暴力法,遍历一遍高度数组heights[],每次遍历一个矩形位置,就对他的左右两边界进行判断,如果左边或右边高度大于等于当前位置,就也可以包括进来,求出面积并和最大面积做对比进行更新。
  • 暴力法的时间复杂度为O(n²),我们可以通过空间换时间的角度来降低时间复杂度为O(n)
  • 我们可以设置一个栈空间来保存每一个位置的索引,因为高度可以通过数组得出,我们只需要知道宽度,就能求出面积。

以下为代码+注释:

    public int largestRectangleArea(int[] heights) {
        int len = heights.length;
        if(len == 0){
            return 0;
        }
        if(len == 1){
            return heights[0];
        }
        int maxRes = 0;
        // 创建一个栈结构,存放矩形的索引
        Deque<Integer> stack = new ArrayDeque<>();
        // 依次遍历每一个矩形
        // 每次都将该索引加入到栈末尾,如果碰到当前位置的高度比前面的小,那么就要对前一个位置的最大面积进行计算了,怎么计算?首先看要计算面积的矩形位置前面还有没有和它高度相同的,有就一并弹出
        for(int i = 0; i < len; i++){
            // 碰到当前位置高度比前面低了,那么一定能求出来前面高的矩形的面积,因为到这里距离变低,就截断了
            while(!stack.isEmpty() && heights[i] < heights[stack.peekLast()]){
                int curWidth = 0;
                // 首先将要求面积的矩形从栈中弹出
                int curHeight = heights[stack.pollLast()];
                // 如果前面有高度和当前高度相同的矩形 ,也一起弹出
                while(!stack.isEmpty() && curHeight == heights[stack.peekLast()]){
                    stack.pollLast();
                }
                if(stack.isEmpty()){
                    curWidth = i;
                }else{
                    // 因为计算的是中间的宽度,因此要-1,不带左右两边边界
                    curWidth = i - stack.peekLast() - 1;
                }
                maxRes = Math.max(maxRes, curWidth * curHeight);
            }
            // 最后不要忘记将当前位置的索引入栈
            stack.addLast(i);
        }
        // 将整个数组遍历一遍之后,如果栈中还有值,说明还有面积没有计算
        while(!stack.isEmpty()){
            int curWidth = 0;
            // 从后向前依次弹出计算
            int curHeight = heights[stack.pollLast()];
            // 如果前面还有和当前矩形高度相同的,那么一并弹出
            while(!stack.isEmpty() && curHeight == heights[stack.peekLast()]){
                stack.pollLast();
            }
            // 这里因为右边已经没有数据了,就把右边界设置为len,也就是假设数组len索引处有一个长度为0的矩形
            if(stack.isEmpty()){
                curWidth = len;
            }else{
                curWidth = len - stack.peekLast() - 1;
            }
            maxRes = Math.max(maxRes, curWidth * curHeight);
        }
        return maxRes;
    }

笔者也在不断学习,如有错误,欢迎指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值