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

84. 柱状图中最大的矩形

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

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

示例 1:

输入:heights = [2,1,5,6,2,3]

输出:10

解释:最大的矩形为图中红色区域,面积为 10

示例 2:

输入: heights = [2,4]

输出: 4

提示:

  • 1 <= heights.length <=10^5
  • 0 <= heights[i] <= 10^4

解法思路(参考官方题解及视频讲解):

1、暴力1 O(n^3)

for i -> 0, n
    for j -> i, n
       (i, j) -> 最小高度,area
       update max-area

2、暴力2 O(n^2)

for i -> 0, n:
    找到 left bound, right bound
        area = height[i] * (right - left)
        update max-area

3、Stack

4、优化 Stack,加哨兵元素

 法一(超时):

class Solution {
    public int largestRectangleArea(int[] heights) {
        // Time: O(n^3)
        // Space: O(1)
        int maxArea = 0;
        for (int i = 0; i < heights.length; i++) {
            for (int j = i; j < heights.length; j++) {
                int minHeight = Integer.MAX_VALUE;
                for (int k = i; k <= j; k++) {
                    minHeight = Math.min(minHeight, heights[k]);
                }
                maxArea = Math.max(maxArea, minHeight * (j - i + 1));
            }
        }
        return maxArea;
    }
}

法二(超时):

class Solution {
    public int largestRectangleArea(int[] heights) {
        // Time: O(n^2)
        // Space: O(1)
        int maxArea = 0;
        for (int i = 0; i < heights.length; i++) {
            int minHeight = Integer.MAX_VALUE;
            for (int j = i; j < heights.length; j++) {
                minHeight = Math.min(minHeight, heights[j]);
                maxArea = Math.max(maxArea, minHeight * (j - i + 1));
            }
        }
        return maxArea;
    }
}

法三:

class Solution {
    public int largestRectangleArea(int[] heights) {
        // Stack 空间换时间
        // 特殊情况1:遍历完成后,栈内元素出栈时一定可以扩展到数组的末尾
        // 特殊情况2:弹出栈顶后栈为空,一定可以扩散到数组最左边
        // 特殊情况3:栈中存在高度相等的元素,出栈
        // Time: O(n)
        // Space: O(n)
        int len = heights.length;
        if (len == 0) return 0;
        if (len == 1) return heights[0];
        int maxArea = 0;
        Deque<Integer> stack = new ArrayDeque<>();
        for (int i = 0; i < len; i++) {
            // 当前元素的高度严格小于栈顶元素的高度时,出栈
            while (!stack.isEmpty() && heights[i] < heights[stack.peekLast()]) {
                int height = heights[stack.removeLast()];
                // 特殊情况3:栈中存在高度相等的元素,出栈
                while (!stack.isEmpty() && heights[stack.peekLast()] == height) {
                    stack.removeLast();
                }
                // 特殊情况2:弹出栈顶后栈为空,一定可以扩散到数组最左边
                int width = stack.isEmpty() ? i : (i - stack.peekLast() - 1);
                maxArea = Math.max(maxArea, width * height);
            }
            stack.addLast(i);
        }
        // 弹出栈中所有元素
        while (!stack.isEmpty()) {
            int height = heights[stack.removeLast()];
            while (!stack.isEmpty() && heights[stack.peekLast()] == height) {
                stack.removeLast();
            }
            // 特殊情况1:遍历完成后,栈内元素出栈时一定可以扩展到数组的末尾
            int width = stack.isEmpty() ? len : (len - stack.peekLast() - 1);
            maxArea = Math.max(maxArea, width * height);
        }
        return maxArea;
    }
}

优化法三:

class Solution {
    public int largestRectangleArea(int[] heights) {
        // Stack(add Sentinel)
        // Time: O(N)
        // Space: O(N)
        int len = heights.length;
        if (len == 0) return 0;
        if (len == 1) return heights[0];
        int maxArea = 0;
        int[] newHeights = new int[len + 2];
        for (int i = 0; i < len; i++) {
            newHeights[i + 1] = heights[i];
        }
        len += 2;
        heights = newHeights;
        Deque<Integer> stack = new ArrayDeque<Integer>();
        stack.addLast(0);
        for (int i = 1; i < len; i++) {
            while (heights[stack.peekLast()] > heights[i]) {
                int height = heights[stack.removeLast()];
                int width = i - stack.peekLast() - 1;
                maxArea = Math.max(maxArea, width * height);
            }
            stack.addLast(i);
        }
        return maxArea;
    }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/288804.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python机器学习】构建简单的k近邻算法模型

k近邻算法是一个很容易理解的算法&#xff0c;构建模型只需要保存训练数据集。要对一个新的数据点做出预测&#xff0c;算法会在训练集中寻找与这个新数据点距离最近的数据点&#xff0c;然后将找到的数据点的标签赋值给这个新数据点。 l近邻算法中k的含义是&#xff1a;我们可…

阿里云系统盘测评ESSD、SSD和高效云盘IOPS、吞吐量性能参数表

阿里云服务器系统盘或数据盘支持多种云盘类型&#xff0c;如高效云盘、ESSD Entry云盘、SSD云盘、ESSD云盘、ESSD PL-X云盘及ESSD AutoPL云盘等&#xff0c;阿里云百科aliyunbaike.com详细介绍不同云盘说明及单盘容量、最大/最小IOPS、最大/最小吞吐量、单路随机写平均时延等性…

H5C3练习心得 2024.01.03(文字加载动画效果)--transition,动画渲染,遮罩层

&#xff08;一&#xff09;transition&#xff08;过渡效果&#xff09; 1.详解 通常将css的属性值更改后&#xff0c;浏览器会立即更新新的样式&#xff0c;例如在鼠标悬停在元素上时&#xff0c;通过 :hover 选择器定义的样式会立即应用在元素上。 在 CSS3 中加入了一项过…

IDEA多实例启动

IDEA多实例启动 1、基本使用 打开它 如果想一个model多实例化启动&#xff0c;选择对应实例&#xff0c;点击 点击apply&#xff0c;出去就有了&#xff0c;但是&#xff0c;创建完之后&#xff0c;还以可点击这里选择compound 真的很nice

Spring ApplicationEvent事件处理

Spring的事件 ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现&#xff0c;内部实现原理是观察者设计模式&#xff0c;设计初衷也是为了系统业务逻辑之间的解耦&#xff0c;提高可扩展性以及可维护性。 ApplicationEvent就是Spring的事件接口Applic…

C++ 实现Windows WIFI管理器

文章目录 前言一、代码二、补充知识三、遇到的问题字符集转换 四、剩余问题总结 前言 出于项目需要&#xff0c;需要用C开发一个wifi界面&#xff0c;实现wifi扫描、wifi连接与断开、wifi密码记住的基础功能。 一、代码 话不多说&#xff0c;直接上代码。 #pragma once #inc…

迎接数字化,亿发专业MES制造管理解决方案,助力湖南企业智能制造管理

在20世纪80年代末&#xff0c;美国先进制造研究机构&#xff08;AMT&#xff09;率先提出了MES&#xff08;Manufacturing Execution System&#xff09;的概念&#xff0c;即制造执行系统或生产实施系统。面向车间的生产过程管理与实时信息管理&#xff0c;解决车间生产任务的…

EasyExcel解决导出字符串变成数字问题

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN博客专家&#xff0c;阿里云签约博主&#xff0c;InfoQ签约博主&#xff0c;华为云云享专家&#xff0c;51CTO明日之星 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f492; 公众号&#xff1a…

CMake入门教程【基础篇】在Windows、Linux上安装CMake

&#x1f608;「CSDN主页」&#xff1a;传送门 &#x1f608;「Bilibil首页」&#xff1a;传送门 &#x1f608;「本文的内容」&#xff1a;CMake入门教程 &#x1f608;「动动你的小手」&#xff1a;点赞&#x1f44d;收藏⭐️评论&#x1f4dd; 文章目录 1.windows平台第1步&…

市场复盘总结 20240103

仅用于记录当天的市场情况,用于统计交易策略的适用情况,以便程序回测 短线核心:不参与任何级别的调整 昨日回顾: 方法一:指标选股 select * from dbo.ResultAll where 入选类型 like %指标选股% and 入选日期=20240103;方法二:趋势选股法 1、最低价持续3日上涨 2、均价…

c 编码(进行中)

编码出来的jpeg图片只有红&#xff0c;绿色。排查中 ​​​​​​​ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #in…

jar包反编译

tips&#xff1a;下载地址在评论区 一、解压出来单击.exe文件 二、 将jar包拖到灰色区域 如图所示 三、保存 1.File->Save All Sourses->解压缩 2.快捷键CtrlAltS

C++面向对象语法总结(一)

一、类 C中可以使用struct、class两个关键字来定义一个类struct和class的区别 struct的默认成员权限是publicclass的默认成员权限是private实际开发中&#xff0c;用class表示类的比较多&#xff0c;因为涉及到封装的思想 在函数中创建的对象&#xff0c;都是在栈空间&#xf…

引导过程与服务控制

一、开机启动的完整过程 bios加电自检测-------mbr------grub----------加载内核文件------------启动第一个进程 简述&#xff1a;加电后bios程序会自检硬件&#xff0c;硬件无故障&#xff0c;会根据第一启动项去找内核&#xff0c;一般来说&#xff0c;第一启动项是硬盘&a…

(学习打卡2)重学Java设计模式之六大设计原则

前言&#xff1a;听说有本很牛的关于Java设计模式的书——重学Java设计模式&#xff0c;然后买了(*^▽^*) 开始跟着小傅哥学Java设计模式吧&#xff0c;本文主要记录笔者的学习笔记和心得。 打卡&#xff01;打卡&#xff01; 六大设计原则 &#xff08;引读&#xff1a;这里…

最新-mybatis-plus 3.5分页插件配置

mybatis-plus 3.5分页插件配置 前提 1.项目不是springboot, 是以前的常规spring项目 2.mp 从3.2升级到3.5&#xff0c;升级后发现原本的分页竟然不起作用了&#xff0c;每次查询都是查出所有 前后配置对比 jar包对比 jsqlparser我这里单独引了包&#xff0c;因为版本太低…

[蓝桥杯2020国赛]答疑

答疑 题目描述 有 n 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。 老师可以安排答疑的顺序&#xff0c;同学们要依次进入老师办公室答疑。 一位同学答疑的过程如下&#xff1a; 首先进入办公室&#xff0c;编号为 i 的同学需要 si​ 毫秒的时间。然后同学问…

深入理解SPi通讯协议

目录 SPI简介&#xff1a; 主设备通过选择线&#xff08;SS&#xff09; 主设备通过时钟线&#xff08;SCLK&#xff09; 主设备通过主输出线&#xff08;MOSI&#xff09; 主设备通过主输出线&#xff08;MISO&#xff09; SPI读写数据&#xff1a; SPI写入数据&#xf…

超详细解释奇异值分解(SVD)【附例题和分析】

目录 一. 矩阵对角化 二. 奇异值分解 三. 对比奇异值分解与特征值分解 四. SVD分解与四大基础子空间 五. SVD分解的正交矩阵 六. 方阵与SVD分解 七. 单位特征向量与SVD分解 八. 例题分析&#xff1a;秩为1 九. 例题分析&#xff1a;秩为2 十. 计算机网络与矩阵的秩 一…

从董宇辉小作文风波,我们普通人能学到些什么?

哈喽&#xff0c;大家好啊&#xff0c;我是雷工&#xff01; 最近董宇辉小作文风波动静太大了&#xff0c;哪哪都是。 打开公号上都在写董宇辉&#xff0c;打开某音&#xff0c;都在说董宇辉。 这种事其实本来就是立场不同&#xff0c;各个角度来说都有道理的事。 神仙打架&am…