Leetcode 剑指 Offer II 039. 直方图最大矩形面积

news2024/11/23 21:27:01

题目难度: 困难

原题链接

今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

给定非负整数数组 heights ,数组中的数字用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 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. 如何优化时间复杂度?

解决方案

思路

  • 分析题目, 最容易想到的思路是暴力两层循环, 具体做法如下:
    • 外层循环遍历每个柱子, 记录其高度 h
    • 内层向左右两边扩展, 直到超出数组范围或低于当前柱子, 记录对应的下标 l 和 r
    • 此时即为使用当前柱子高度时的矩形, 计算其面积 (r-l-1)*h 并更新最终结果
    • 这样遍历完成后就覆盖了所有可能的矩形, 其最大面积即为所求
  • 暴力算法虽然简单, 但其时间复杂度达到了 O(N^2), 根据题目输入规模, 肯定会超时, 如何优化呢?
  • 我们的目的是计算所有矩形的面积, 而高度是已知的, 如何快速得到每个柱子的左右边界呢?
  • 由于柱子的左右边界需低于当前柱子, 而且我们既需要知道高度, 又需要知道宽度(下标), 所以这里可以采用单调栈存下标的方式实现, 具体做法如下:
    • 单调栈存柱子下标, 且保证从栈顶到栈底的高度递减
    • 遍历某个柱子时, 先将其与栈顶高度比较
      • 如果栈顶更高, 则将栈顶弹出, 保证单调性, 同时栈顶对应的矩形面积也可以计算了, 其右边界就是当前柱子, 左边界就是栈顶下面一个元素或者-1(对应栈顶左边没有更低柱子的情况), 右-左-1就是矩形的宽
      • 否则就退出循环, 将当前柱子压入栈中, 此时栈顶到栈底的高度仍是递减的
    • 遍历完所有柱子后, 栈中仍可能存在一些柱子, 此时说明这些柱子右边没有更高的柱子, 其右边界就是数组长度, 左边界和上面情况一样, 依次将其弹出并计算面积
    • 最终结果就是上述所有矩形面积的最小值
  • 利用单调栈, 我们使用和暴力算法一样的思路计算所有矩形面积, 但却将时间复杂度成功降低到了 O(N), 因为每个柱子只需要处理两次(一次入栈一次出栈)
  • 下面的代码就对应了上面的整个过程, 并且有详细的注释, 方便大家理解

复杂度

  • 时间复杂度 O(N): 数组每个元素最多处理 2 遍 (压入和弹出栈)
  • 空间复杂度 O(N): 栈最多存 N 个元素

代码

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        # stack存储柱子的下标, 且其高度满足从栈顶到栈底递减
        stack = []
        res = 0
        for r, h in enumerate(heights):
            while stack and heights[stack[-1]] > h:
                # 栈顶高度大于当前高度, 可以计算栈顶柱子对应的矩形面积了
                # 栈顶柱子的右边界r就是当前下标, 左边界l是上一个栈顶或-1(上一个栈顶不存在时)
                ch = heights[stack.pop()]
                l = -1 if not stack else stack[-1]
                # 宽*高
                res = max(res, (r - l - 1) * ch)
            stack.append(r)
        # 如果遍历结束后栈中仍有元素, 则说明这些柱子右边没有比它更低的柱子了, 需要计算它们对应的矩形面积
        while stack:
            ch = heights[stack.pop()]
            # 栈顶柱子的右边界r就是数组长度, 左边界l是上一个栈顶或-1(上一个栈顶不存在时)
            r = len(heights)
            l = -1 if not stack else stack[-1]
            # 宽*高
            res = max(res, (r - l - 1) * ch)
        return res

大家可以在下面这些地方找到我~😊

我的 GitHub

我的 Leetcode

我的 CSDN

我的知乎专栏

我的头条号

我的牛客网博客

我的公众号: 算法精选, 欢迎大家扫码关注~😊

算法精选 - 微信扫一扫关注我

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大脑营行|“福安市华龙教育基金”支持家乡教育事业发展

8月8日&#xff0c;福安市松罗中学举行“福安市华龙教育基金”中考奖学金颁发仪式。福安市松罗乡党委书记钟文、乡长郑仁寿、福安市人民政府教育督导室副科级督导员&#xff08;片区领导&#xff09;陈秦、校长张明亮、各村支部书记、家长代表、受奖学生&#xff0c;校领导班子…

LabVIEW使用图像处理进行交通控制性能分析

LabVIEW使用图像处理进行交通控制性能分析 采用普雷维特、拉普拉斯、索贝尔和任意的空间域方法对存储的图像进行边缘检测&#xff0c;并获取实时图像。然而&#xff0c;对四种不同空间域边缘检测方法的核的性能分析。 以前&#xff0c;空路图像存储在数据库中&#xff0c;道路…

C语言实例_调用SQLITE数据库完成数据增删改查

一、SQLite介绍 SQLite是一种轻量级的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是一个开源的、零配置的、服务器端的、自包含的、零管理的、事务性的SQL数据库引擎。它被广泛应用于嵌入式设备、移动设备和桌面应用程序等领域。 SQLite的特点包括&…

使用wxPython和PyMuPDF在Python中显示PDF目录的实现

展示如何使用wxPython和PyMuPDF库在Python中选择PDF文件并将目录显示在列表框中。 简介&#xff1a; 在本篇教程中&#xff0c;我们将学习如何使用wxPython和PyMuPDF库在Python中选择PDF文件&#xff0c;并将其目录显示在一个列表框中。这将使用户能够方便地浏览PDF文档的目录…

每天一道leetcode:72. 编辑距离(动态规划困难)

今日份题目&#xff1a; 给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&#xff1a; 插入一个字符 删除一个字符 替换一个字符 示例1 输入&#xff1a;word1 "horse", word…

文心一言 VS 讯飞星火 VS chatgpt (75)-- 算法导论7.2 4题

四、如果用go语言&#xff0c;银行一般会按照交易时间来记录某一账户的交易情况。但是&#xff0c;很多人却喜欢收到的银行对账单是按照支票号码的顺序来排列的。这是因为&#xff0c;人们通常都是按照支票号码的顺序来开出支票的&#xff0c;而商人也通常都是根据支票编号的顺…

centos7升级glibc2.28

1 概述 centos7自带的glibc对于某些软件是太旧的&#xff0c;决定将glibc升级至2.28。 2 安装过程 2.1 下载glibc源码 mkdir -p /opt/third-party && cd /opt/third-party wget http://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz tar -xf glibc-2.28.tar.gz cd glibc…

ubuntu下gif动态图片的制作

Gif图片比视频小, 比静态JPG图片形象生动, 更适用于产品展示和步骤演示等。各种各样的gif动图为大家交流提供很大的乐趣. 这里简单介绍ubuntu系统下gif图的制作。 一、工具安装: kazam和ffmpeg kazam是linux下的一款简单但是功能强大的屏幕录制工具. 它可录制声音并选择全屏录…

【Kali】vmware虚拟机三种网络连接方式,ms17-010 , ms08_067的复现

【Kali】vmware虚拟机三种网络连接方式&#xff0c;ms17-010 &#xff0c; ms08_067的复现 nmapmsfconsolevmware虚拟机三种网络连接方式ms17-010ms08_067 kali中对windowsXP、windows 7漏洞利用使用到的工具&#xff1a;nmap、msfconsole。 nmap nmap是一个网络连接端扫描软件…

FL Studio 21最新for Windows-21.1.0.3267中文解锁版安装激活教程及更新日志

FL Studio 21最新版本for Windows 21.1.0.3267中文解锁版是最新强大的音乐制作工具。它可以与所有类型的音乐一起创作出令人惊叹的音乐。它提供了一个非常简单且用户友好的集成开发环境&#xff08;IDE&#xff09;来工作。这个完整的音乐工作站是由比利时公司 Image-Line 开发…

QT编译fabs not declared in this scope

使用MinGW进行编译出现如下情况。 这种查了不少资料都没有解决&#xff0c;因为在使用微软的编译器不存在这个问题。 后面发现只需要在加入头文件 #include <math.h>就可以解决了。

opencv图片灰度二值化

INCLUDEPATH D:\work\opencv_3.4.2_Qt\include LIBS D:\work\opencv_3.4.2_Qt\x86\bin\libopencv_*.dll #include <iostream> #include<opencv2/opencv.hpp> //引入头文件using namespace cv; //命名空间 using namespace std;//opencv这个机器视…

在线吉他调音

先看效果&#xff08;图片没有声&#xff0c;可以下载源码看看&#xff0c;比这更好~&#xff09;&#xff1a; 再看代码&#xff08;查看更多&#xff09;&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&quo…

无涯教程-Perl - readdir函数

描述 此函数在标量context中从与DIRHANDLE关联的目录返回下一个目录条目。在列表context中,返回DIRHANDLE中的所有其余目录条目。 语法 以下是此函数的简单语法- readdir DIRHANDLE返回值 此函数在标量context中从与DIRHANDLE关联的目录返回下一个目录条目。在列表context…

文件高效管理,自动新建多个同名文件夹并分类整理大量文件

你有没有遇到过需要新建大量同名文件夹并分类整理海量文件的情况&#xff1f;如果是&#xff0c;那么我们的文件管理软件将会是你的救星&#xff01;我们的软件将帮助你轻松实现自动新建多个同名文件夹&#xff0c;并帮助你高效地分类整理大量文件。让我们来告诉你一些使用我们…

LeetCode 1631. Path With Minimum Effort【最小瓶颈路;二分+BFS或DFS;计数排序+并查集;最小生成树】1947

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

音画欣赏|《亲亲湖边水》

《亲亲湖边水》60x50cm陈可之1988年绘 贝加尔湖畔 【李健】 在我的怀里 在你的眼里 那里春风沉醉 那里绿草如茵 月光把爱恋 洒满了湖面 两个人的篝火 照亮整个夜晚 多少年以后 如云般游走 那变换的脚步 让我们难牵手 这一生一世 有多少你我 被吞没在月光如水的夜里 多想某…

「何」到底该读「なん」还是「なに」?柯桥学日语

「何」到底该读「なん」还是「なに」&#xff1f; 首先&#xff0c;讲一个规律&#xff0c;大家记住就行。当「何」后面所接单词的第一个发音在“た”、“だ”、“な”行时&#xff0c;读作“なん”。一般这种情况下&#xff0c;后面跟的是の、でも、です和だ。 用例&#xff…

Ubuntu安装bfloat16==1.1出现问题 error: subprocess-exited-with-error

报错 error: subprocess-exited-with-error python setup.py bdist_wheel did not run successfully. 解决方法 确保你的系统上已经安装了 C/C 编译器&#xff08;如 gcc、g&#xff09;。 如果你使用的是 Linux 系统&#xff0c;你可以使用包管理器来安装它们。命令如下 u…

华为OD机试真题 Java 实现【数组去重和排序】【2023 B卷 100分】

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…