84. 柱状图中最大的矩形【困难】

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

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

示例 1:

复制代码
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

示例 2:

复制代码
输入: heights = [2,4]
输出: 4

一、单调栈

思路:

这题考的基础模型其实就是:在一维数组中对每一个数找到第一个比自己小的元素。这类"在一维数组中找第一个满足某种条件的数"的场景就是典型的单调栈应用场景。

这一题需要找到是每一个柱子左边和右边第一个比它矮的柱子,我们取它俩的下标,然后用

right - left - 1来计算矩形的宽,这样我们就可以计算出以这个柱子为高度的最大矩形的面积。

我们定义一个单调递增的栈来存数组元素的下标,也就是在遍历数组时,每次只压入更大的元素的下标,并且在遍历时判断该元素 x 是否大于栈顶元素,若大于则入栈,若小于则 x 元素的下标就是右边界,而左边界就是栈中的第二个元素,找到了左右两边小于 栈顶 元素的下标,就能计算宽,再乘以 栈顶 元素的值,就得到以 栈顶 元素的值 为高的矩形的面积。

注意我们找到的是以 栈顶元素的值 为高的矩形的面积,不是 元素 x。要做弹出栈顶元素的操作。

如果左边界 也就是栈中第二个元素没有了,栈为空了,那就记左边界为 -1,这样计算是对的,已经经过数学验证。如果遍历完数组,栈中还有元素,那么这些元素的右边界都是数组末尾,左边界还是栈中第二个元素,我们分别计算完这些剩余元素对应的矩形面积。

有一个小技巧,在数组最后加一个元素 0 ,用来处理遍历完后栈中剩余的元素,加上末尾 0 后,当遍历到最后,这样在比较栈顶元素和当前元素时,当前元素为0,那一定小于栈顶元素,都能找到右边界 0 的下标,都能按照非剩余元素那样计算面试,就可以和非剩余元素用一样的代码计算。不用再写新代码处理栈中剩余元素。

时间复杂度O(n)

代码:

java 复制代码
class Solution {
    public int largestRectangleArea(int[] heights) {
        int maxArea = 0;
        int n = heights.length;
        Stack<Integer> stack = new Stack<>();

        for(int i = 0; i <= n; i++){
            // 末尾加一个0,让处理栈中剩余元素和处理非剩余元素用一样的代码
            int curHeight = (i == n) ? 0 : heights[i];

            // 栈不为空且该元素小于栈顶元素
            while(!stack.isEmpty() && curHeight < heights[stack.peek()]){
                // 计算高
                int height = heights[stack.pop()];

                // 计算宽,这里很巧妙,因为上面已经pop出栈了栈顶元素,所以这里的peek是栈中第二个元素,也就左边界
                int width = stack.isEmpty() ? i : i - stack.peek() - 1;

                maxArea = Math.max(maxArea, height * width);
            }

            stack.push(i);
        }

        return maxArea;
    }
}
相关推荐
一匹电信狗2 小时前
【LeetCode_547_990】并查集的应用——省份数量 + 等式方程的可满足性
c++·算法·leetcode·职场和发展·stl
鱼跃鹰飞3 小时前
Leetcode会员尊享100题:270.最接近的二叉树值
数据结构·算法·leetcode
梵刹古音4 小时前
【C语言】 函数基础与定义
c语言·开发语言·算法
筵陌4 小时前
算法:模拟
算法
We་ct5 小时前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
renhongxia15 小时前
AI算法实战:逻辑回归在风控场景中的应用
人工智能·深度学习·算法·机器学习·信息可视化·语言模型·逻辑回归
CoderCodingNo5 小时前
【GESP】C++四级/五级练习题 luogu-P1223 排队接水
开发语言·c++·算法
民乐团扒谱机5 小时前
【AI笔记】精密光时频传递技术核心内容总结
人工智能·算法·光学频率梳
CoderCodingNo6 小时前
【GESP】C++五级/四级练习题 luogu-P1413 坚果保龄球
开发语言·c++·算法
2301_822366356 小时前
C++中的命令模式变体
开发语言·c++·算法