LeetCode题练习与总结:柱状图中最大的矩形--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. 创建一个栈,用于存储柱子的索引。

2. 遍历每个柱子,对于当前遍历到的柱子,执行以下操作:

  • 当栈不为空且当前柱子的高度小于栈顶柱子的高度时,说明找到了栈顶柱子右边的第一个小于它的柱子,可以计算栈顶柱子的最大面积。此时,栈顶柱子左边第一个小于它的柱子是栈中下一个元素,右边第一个小于它的柱子是当前遍历到的柱子。因此,可以计算出栈顶柱子的最大面积,并将其从栈中弹出。重复这个步骤,直到栈为空或者栈顶柱子的高度小于等于当前柱子的高度。
  • 将当前柱子的索引入栈。

3. 遍历完成后,栈中可能还有柱子的索引。这些柱子右边没有小于它的柱子,因此可以认为右边第一个小于它的柱子是数组的最右端。对于栈中剩余的每个柱子,重复步骤2中的面积计算过程。

4. 在整个过程中,记录下最大的面积,最后返回这个面积。

三、具体代码

class Solution {
    public int largestRectangleArea(int[] heights) {
        int maxArea = 0;
        Deque<Integer> stack = new LinkedList<>();
        int[] extendedHeights = new int[heights.length + 2]; // 扩展数组,首尾各添加一个高度为0的柱子
        System.arraycopy(heights, 0, extendedHeights, 1, heights.length);

        for (int i = 0; i < extendedHeights.length; i++) {
            while (!stack.isEmpty() && extendedHeights[i] < extendedHeights[stack.peek()]) {
                int height = extendedHeights[stack.pop()];
                int width = i - stack.peek() - 1;
                maxArea = Math.max(maxArea, height * width);
            }
            stack.push(i);
        }

        return maxArea;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 我们遍历了扩展后的数组一次,其中 n 是原始数组 heights 的长度。
  • 在每次迭代中,我们可能会弹出栈中的元素,并且每个元素最多只会被弹出一次。
  • 因此,尽管内部有 while 循环,但每个元素只会被处理一次,所以总的时间复杂度是 O(n)。
2. 空间复杂度
  • 我们使用了一个栈来存储索引,在最坏的情况下,数组中的所有元素都按顺序入栈一次,因此栈的大小为 O(n)。
  • 我们还使用了一个扩展数组 extendedHeights,其长度为原始数组长度加上2,因此空间复杂度也是 O(n)。
  • 除了栈和扩展数组之外,我们只使用了固定数量的额外空间,如循环变量等,这些额外的空间使用不依赖于输入数组的大小。

五、总结知识点

1. 单调栈(Monotonic Stack)

  • 单调栈是一种特殊的栈结构,用于解决一类需要维护数据单调性的问题。
  • 在这个问题中,我们使用单调递增栈来维护柱子的高度,以便快速找到每个柱子左右两边第一个比它矮的柱子。

2. 数组操作

  • System.arraycopy() 方法用于数组拷贝,将原数组 heights 的内容拷贝到扩展数组 extendedHeights 中。
  • 扩展数组在原数组的首尾各添加了一个高度为0的柱子,以便在遍历结束时能够计算所有剩余在栈中的柱子的面积。

3. 链表(LinkedList)

  • Deque<Integer> 接口和 LinkedList<Integer> 类是 Java 中用于实现栈和队列的数据结构。
  • 在这个问题中,我们使用 LinkedList 作为栈,用于存储柱子的索引。

4. 循环(Loop)

  • for 循环用于遍历扩展后的数组。

5. 条件语句(Conditional Statements)

  • while 循环和 if 语句用于根据条件执行不同的代码路径。
  • 在这个问题中,while 循环用于在当前柱子高度小于栈顶柱子高度时,计算栈顶柱子的最大面积并将其从栈中弹出。

6. 算法设计

  • 这个问题涉及到算法设计,即如何高效地计算最大矩形面积。
  • 通过使用单调栈,我们可以在 O(n) 的时间复杂度内解决这个问题,这比暴力解法(O(n^2))更高效。

7. 数学运算

  • 矩形面积的计算涉及到基本的乘法运算。

8. 函数和方法调用

  • Math.max() 方法用于比较并返回两个数中的最大值。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

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

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

相关文章

【分布式系统】FLP、CAP、BASE、ACID理论简介

分布式系统一致性模型 在说FLP&#xff0c;CAP&#xff0c;BASE&#xff0c;ACID理论前&#xff0c;必须先说说分布式系统的一致性模型&#xff0c;它是其他理论的基础知识。 依次介绍几个相关的概念&#xff1a; 分布式系统是由多个不同的服务节点组成&#xff0c;节点与节…

Java将文件目录转成树结构

在实际开发中经常会遇到返回树形结构的场景&#xff0c;特别是在处理文件系统或者是文件管理系统中。下面就介绍一下怎么将文件路径转成需要的树形结构。 在Java中&#xff0c;将List<String>转换成树状结构&#xff0c;需要定义一个树节点类&#xff08;TreeNode&#…

【linux】初步认识文件系统

初步认识文件系统 前置知识的简单了解简单回顾C语言的文件操作stdin&stdout&stderr 系统文件IOopen函数的返回值文件描述符fd打开文件背后的操作文件描述符的分配规则 前置知识的简单了解 文件包括了文件内容和文件属性两个部分(文件内容顾名思义就是文件里面的数据等…

VBA 读取sheet页中的指定区域数据,生成CSV文件

⏹待生成数据的sheet页 ⏹VBA代码 CreateObject("ADODB.Stream")&#xff1a;Microsoft ActiveX Data Objects (ADO) 库中的一个对象&#xff0c;用来处理文件的读写操作。Application.PathSeparator&#xff1a;系统默认的分隔符。Const startRowNum 4&#xff1a…

OpenCV(四)—— 车牌号识别

本节是车牌识别的最后一部分 —— 车牌字符识别&#xff0c;从一个完整的车牌图片到识别出车牌上的字符大致需要如下几步&#xff1a; 预处理&#xff1a;将车牌图片灰度化、二值化&#xff0c;并去除识别时的干扰因素&#xff0c;比如车牌铆钉字符分割&#xff1a;将整个车牌…

for循环赋值

在for循环内将i赋值给j的问题 for(int i0,ji1;i<5;i){//此时j只会等于1cout<<"i-"<<i<<" j-"<<j<<endl; }如图&#xff1a; 将j放入循环体后没问题 for(int i0;i<5;i){int j i1; cout<<"i-"<<…

关于一个error C2664错误代码的解析

具体错误信息如下所示&#xff1a; error C2664: “osgEarth::UID osgEarth::Util::ShaderFactory::addPreProcessorCallback(osg::Referenced *,std::function<void (std::string &,osg::Referenced *)>)”: 无法将参数 2 从“osgEarth::Util::PbrLightEffect::att…

40 生产者消费者模型

生产者消费者模型 概念 为何要使用生产者消费者模型&#xff0c;这个是用过一个容器解决生产者和消费的强耦合问题。生产者和消费者之间不需要通讯&#xff0c;通过阻塞队列通讯&#xff0c;所以生产者生产完数据之后不用等待消费者处理&#xff0c;直接扔给阻塞队列&#xf…

41.WEB渗透测试-信息收集-域名、指纹收集(3)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;40.WEB渗透测试-信息收集-域名、指纹收集&#xff08;2&#xff09; 关于oneforall的安装…

DRF视图源码分析

DRF视图源码分析 1 APIView class GenericAPIView(APIView):pass # 10功能class GenericViewSet(xxxx.View-2个功能, GenericAPIView):pass # 5功能能class UserView(GenericViewSet):def get(self,request):passAPIView是drf中 “顶层” 的视图类&#xff0c;在他的内部主要…

SpringBoot+阿里云实现验证码登录注册及重置密码

开通阿里云短信服务 阿里云官网 创建API的Key 可以使用手机号或者刷脸来进行创建Key 创建成功 开通完成以后接下来实现代码请求阶段 配置maven依赖 <!-- 阿里云 oss 短信 依赖--><dependency><groupId>com.aliyun</groupId><artifactId>dysm…

Python的使用

1、打印&#xff1a;print&#xff08;‘hello’&#xff09; 2、Python的除法是数学意义上的除法 print&#xff08;2/3&#xff09; 输出&#xff1a;0.6666... 3、a18 a‘hello’ print(a) 可以直接输出 4、**2 表示2的平方 5、打印类型 print&#xff08;type&am…

【深度学习】第二门课 改善深层神经网络 Week 1 深度学习的实践层面

&#x1f680;Write In Front&#x1f680; &#x1f4dd;个人主页&#xff1a;令夏二十三 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;深度学习 &#x1f4ac;总结&#xff1a;希望你看完之后&#xff0c;能对…

R语言学习—6—多元相关与回归分析

1、引子 xc(171,175,159,155,152,158,154,164,168,166,159,164) #身高 yc(57,64,41,38,35,44,41,51,57,49,47,46) #体重 par(marc(5,4,2,1)) #设定图距离画布边缘的距离&#xff1a;下5&#xff0c;左4&#xff0c;上2&#xff0c;右1 plot(x,y) 2、相关…

【华为 ICT HCIA eNSP 习题汇总】——题目集20

1、&#xff08;多选&#xff09;若两个虚拟机能够互相ping通&#xff0c;则通讯过程中会使用&#xff08;&#xff09;。 A、虚拟网卡 B、物理网卡 C、物理交换机 D、分布式虚拟交换机 考点&#xff1a;数据通信 解析&#xff1a;&#xff08;AD&#xff09; 物理网卡是硬件设…

webpack 常用插件

clean-webpack-plugin 这个插件的主要作用是清除构建目录中的旧文件&#xff0c;以确保每次构建时都能得到一个干净的环境。 var { CleanWebpackPlugin } require("clean-webpack-plugin") const path require("path");module.exports {mode: "de…

docker 基础命令

docker 安装 更新系统 sudo apt update sudo apt -y dist-upgrade安装docker sudo apt-get -y install ca-certificates curl gnupg lsb-release sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/…

数据结构——链表(精简易懂版)

文章目录 链表概述链表的实现链表的节点&#xff08;单个积木&#xff09;链表的构建直接构建尾插法构建头插法构建 链表的插入 总结 链表概述 1&#xff0c;链表&#xff08;Linked List&#xff09;是一种常见的数据结构&#xff0c;用于存储一系列元素。它由一系列节点&…

双链表的应用

cf edu161 D. Berserk Monsters 思路&#xff1a; 因为考虑到&#xff0c;每个怪是否死亡与其左右的怪息息相关&#xff0c;再者&#xff0c;若当前怪死亡&#xff0c;周围怪的相邻信息也会产生变化&#xff0c;由此可以想到使用双链表进行维护&#xff0c;双链表的维护方式有…

STM32——中断篇

技术笔记&#xff01; 1 中断相关概念 1.1 什么是中断&#xff1f; 中断是单片机正在执行程序时&#xff0c;由于内部或外部事件的触发&#xff0c;打断当前程序&#xff0c;转而去处理这一事件&#xff0c;当处理完成后再回到原来被打断的地方继续执行原程序的过程。 在AR…