力扣第84 题柱状图中最大的矩形 C++ 单调栈 Java

题目

84. 柱状图中最大的矩形

困难

相关标签

栈   数组   单调栈

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

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

示例 1:

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

示例 2:

输入: heights = [2,4]
输出: 4

提示:

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104

思路和解题方法

  1. int result = 0;:初始化结果变量为0,用来存放最大矩形面积。
  2. stack<int> st;:声明一个整型栈st,用来存放数组元素的下标。
  3. heights.insert(heights.begin(), 0);:在heights数组头部插入一个值为0的元素。
  4. heights.push_back(0);:在heights数组尾部插入一个值为0的元素。
  5. st.push(0);:将0这个下标入栈。

接下来是for循环,遍历heights数组:

  1. for (int i = 1; i < heights.size(); i++):从下标1开始遍历heights数组。
  2. if (heights[i] > heights[st.top()]):如果当前高度大于栈顶元素所对应的高度,则将当前下标入栈。
  3. else if (heights[i] == heights[st.top()]):如果当前高度等于栈顶元素所对应的高度,则不做任何操作。
  4. else:如果当前高度小于栈顶元素所对应的高度,进入循环。
  5. while (!st.empty() && heights[i] < heights[st.top()]):当栈不为空且当前高度小于栈顶元素所对应的高度时,执行循环。
  6. int mid = st.top(); st.pop();:取出栈顶元素的下标,并将其出栈。
  7. if (!st.empty()):如果栈不为空,说明存在左边界。
  8. int left = st.top(); int right = i;:获取左边界和右边界的下标。
  9. int w = right - left - 1; int h = heights[mid];:计算矩形的宽度和高度。
  10. result = max(result, w * h);:更新最大矩形面积。

最后,返回计算得到的最大矩形面积result。

复杂度

        时间复杂度:

                O(n)

时间复杂度为O(n),其中n是输入数组heights的长度。因为在一次遍历中,每个元素最多被压入和弹出栈各一次,所以总的操作次数与输入数组的长度成线性关系。

        空间复杂度

                O(n)

空间复杂度为O(n),主要是由栈st所使用的额外空间造成的。

c++ 代码


class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int result = 0; // 初始化最大面积为0
        stack<int> st; // 定义一个栈来辅助计算
        heights.insert(heights.begin(), 0); // 数组头部加入元素0
        heights.push_back(0); // 数组尾部加入元素0
        st.push(0); // 将0入栈作为起始位置

        // 从下标1开始遍历数组
        for (int i = 1; i < heights.size(); i++) {
            if (heights[i] > heights[st.top()]) { // 情况一:当前高度大于栈顶高度,入栈
                st.push(i);
            } else if (heights[i] == heights[st.top()]) { // 情况二:当前高度等于栈顶高度,可以忽略
                st.pop(); // 这个可以加,可以不加,效果一样,思路不同
                st.push(i);
            } else { // 情况三:当前高度小于栈顶高度,需要计算面积并更新最大面积
                while (!st.empty() && heights[i] < heights[st.top()]) { // 注意是while
                    int mid = st.top(); // 弹出栈顶元素作为矩形的高度
                    st.pop();
                    if (!st.empty()) {
                        int left = st.top(); // 获取左边界
                        int right = i; // 获取右边界
                        int w = right - left - 1; // 计算宽度
                        int h = heights[mid]; // 获取高度
                        result = max(result, w * h); // 更新最大面积
                    }
                }
                st.push(i); // 将当前位置入栈
            }
        }
        return result; // 返回最大面积
    }
};

简洁代码

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        stack<int> st; // 创建一个整型栈st,用来存放数组元素的下标
        heights.insert(heights.begin(), 0); // 在heights数组头部插入一个值为0的元素
        heights.push_back(0); // 在heights数组尾部插入一个值为0的元素
        st.push(0); // 将0这个下标入栈
        int result = 0; // 初始化结果变量为0,用来存放最大矩形面积
        for (int i = 1; i < heights.size(); i++) { // 遍历heights数组
            while (heights[i] < heights[st.top()]) { // 当当前高度小于栈顶元素所对应的高度时,执行循环
                int mid = st.top();
                st.pop(); // 取出栈顶元素的下标,并将其出栈
                int w = i - st.top() - 1; // 计算矩形的宽度
                int h = heights[mid]; // 获取矩形的高度
                result = max(result, w * h); // 更新最大矩形面积
            }
            st.push(i); // 将当前下标入栈
        }
        return result; // 返回计算得到的最大矩形面积
    }
};

Java代码

class Solution {
    public int largestRectangleArea(int[] heights) {
        // 创建一个新数组newHeight,长度比原数组heights多2,并在两端补0
        int[] newHeight = new int[heights.length + 2];
        System.arraycopy(heights, 0, newHeight, 1, heights.length); // 复制heights数组到newHeight数组
        newHeight[heights.length+1] = 0; // 在newHeight数组末尾加入一个值为0的元素
        newHeight[0] = 0; // 在newHeight数组头部加入一个值为0的元素

        Stack<Integer> stack = new Stack<>(); // 创建一个整型栈stack,用来存放数组元素的下标
        stack.push(0); // 将0这个下标入栈

        int res = 0; // 初始化结果变量为0,用来存放最大矩形面积
        for (int i = 1; i < newHeight.length; i++) { // 遍历newHeight数组
            while (newHeight[i] < newHeight[stack.peek()]) { // 当当前高度小于栈顶元素所对应的高度时,执行循环
                int mid = stack.pop(); // 取出栈顶元素的下标,并将其出栈
                int w = i - stack.peek() - 1; // 计算矩形的宽度
                int h = newHeight[mid]; // 获取矩形的高度
                res = Math.max(res, w * h); // 更新最大矩形面积
            }
            stack.push(i); // 将当前下标入栈
        }
        return res; // 返回计算得到的最大矩形面积
    }
}

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

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

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

相关文章

MySQL(18):MySQL8.0的其它新特性

MySQL从5.7版本直接跳跃发布了8.0版本。 MySQL8.0 新增特征 1.更简便的NoSQL支持。 NoSQL泛指非关系型数据库和数据存储。随着互联网平台的规模飞速发展&#xff0c;传统的关系型数据库已经越来越不能满足需求。从5.6版本开始&#xff0c;MySQL就开始支持简单的NoSQL存储功能…

给女朋友开发个小程序低价点外卖吃还能赚钱

前言 今天又是无聊的一天,逛了下GitHub,发现一个库里面介绍美团饿了吗外卖红包外卖优惠券,先领红包再下单。外卖红包优惠券,cps分成,别人领红包下单,你拿佣金。哇靠,那我岂不是可以省钱还可以赚钱,yyds。。。。想想都美好哈哈哈!!! 回到正题,这个是美团饿了么分销…

基于51单片机电子钟温度计数码显示设计( proteus仿真+程序+设计报告+讲解视频)

这里写目录标题 ✅1.主要功能&#xff1a;✅讲解视频&#xff1a;✅2.仿真设计✅3. 程序代码✅4. 设计报告✅5. 设计资料内容清单&&下载链接✅[资料下载链接&#xff1a;](https://docs.qq.com/doc/DS0Nja3BaQmVtWUpZ) 基于51单片机电子钟温度检测数码显示设计( proteu…

【文件读取/包含】任意文件读取漏洞 afr_3

1.1漏洞描述 漏洞名称任意文件读取漏洞 afr_3漏洞类型文件读取/包含漏洞等级⭐⭐⭐⭐⭐漏洞环境docker攻击方式 1.2漏洞等级 高危 1.3影响版本 暂无 1.4漏洞复现 1.4.1.基础环境 靶场docker工具BurpSuite 1.4.2.环境搭建 1.创建docker-compose.yml文件 version: 3.2 servi…

VSCode配置ESP-IDF

参考其他 文章即可 如果编译时遇到问题&#xff0c;就去找环境变量&#xff0c;多半是环境变量没有配置好。根据自己安装的idf的目录重新配置 环境变量. 如果电脑上有python环境&#xff0c;但是编译时出现找不到python解释器&#xff0c;需要执行下面命令&#xff0c;另外重…

modbus-RTU是一种比较简单、可靠的协议

modbus-RTU是一种比较简单、可靠的协议 RTU, 是modbus中的一种应用层协议&#xff0c;在OSI的第七层 数据格式 应用

环境检测lims系统 环境检测行业实验室管理系统

白码环境监测实验室管理系统针对实验室管理中遇到的问题和难点&#xff0c;提供对环境监测实验室所有监测业务的全流程管理&#xff0c;实现对实验室“人、机、料、法、环”(即人员、仪器、样品、方法、环境)的全面资源管理&#xff0c;实现环境监测实验室工作的自动化和规范化…

基于springboot+vue大学生社团活动管理系统

基于springbootvue大学生社团活动管理系统 摘要 本文介绍了一种基于Spring Boot和Vue.js的大学生社团活动管理系统的设计与实现。社团活动在大学生活中扮演着重要角色&#xff0c;而有效的管理系统可以帮助提高社团活动的组织性和效率。本系统采用了前后端分离的架构&#xff0…

Javaweb之Vue的概述

2.1 Vue概述 通过我们学习的htmlcssjs已经能够开发美观的页面了&#xff0c;但是开发的效率还有待提高&#xff0c;那么如何提高呢&#xff1f;我们先来分析下页面的组成。一个完整的html页面包括了视图和数据&#xff0c;数据是通过请求 从后台获取的&#xff0c;那么意味着我…

2023年【陕西省安全员C证】最新解析及陕西省安全员C证试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 陕西省安全员C证最新解析根据新陕西省安全员C证考试大纲要求&#xff0c;安全生产模拟考试一点通将陕西省安全员C证模拟考试试题进行汇编&#xff0c;组成一套陕西省安全员C证全真模拟考试试题&#xff0c;学员可通过…

SQL note2:DIsks and Files

目录 1、内存和磁盘 2、磁盘API 3、磁盘结构 4、访问磁盘页面 5、磁盘 vs SSD 5、磁盘空间管理 6、Files, Pages, Records 7、选择文件类型 8、堆文件 1&#xff09;链表实现 2&#xff09;页面目录实现 9、排序文件 10、关于计算标题页的注意事项 11、记录类型 …

网络编程TCP/UDP

1 网络通信概述 1.1 IP 和端口 所有的数据传输&#xff0c;都有三个要素 &#xff1a;源、目的、长度。 怎么表示源或者目的呢&#xff1f;请看图 所以&#xff0c;在网络传输中需要使用“IP 和端口”来表示源或目的。 1.2 网络传输中的 2 个对象&#xff1a;server 和 clie…

基于单片机的汽车安全气囊系统故障仿真设计

**单片机设计介绍&#xff0c; 基于单片机微波炉加热箱系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的汽车安全气囊系统的故障检测系统是一种用于检测安全气囊系统故障的智能化设备&#xff0c;通过单片机控…

WPF小知识

在编写WPF程序遇到一些小问题&#xff0c;所以记录起来&#xff0c;查其他方便。 Label自动换行 网上搜的都不能自动换行&#xff0c;发现使用Run 就可以。在脚本中直接调用labTip.Text进行赋值就可以了。 <Label Foreground"#FF9E9E9E" FontSize"16"…

[Android]创建TabBar

创建一个包含“首页”、“分类”和“我的”选项卡的TabBar并实现切换功能&#xff0c;通常可以通过使用TabLayout结合ViewPager或ViewPager2来完成。以下是一个基本的示例&#xff0c;展示了如何使用Kotlin和XML来实现这个功能。 1.添加依赖项到build.gradle dependencies {/…

pg_bouncer在使用中的坑勿踩

目录 简介 环境信息 问题配置 问题配置 启动pgbouncer 链接逻辑图 测试存在问题 pgadmin4 Idea JAVA调用 ​编辑 dbeaver 建议&#xff1a; 简介 前面文章说过关于pg_bouncer的安装讲解&#xff0c;这里讲一下在使用中的坑&#xff0c;在进行配置的时候需要注意。 …

Linux设备树(DTS)介绍

Dts&#xff1a;DTS即Device Tree Source&#xff0c;是一个文本形式的文件&#xff0c;用于描述硬件信息。一般都是固定信息&#xff0c;无法变更&#xff0c;无法overlay。 设备树由来 linux内核源码中&#xff0c;之前充斥着大量的平台相关&#xff08;platform Device&…

《算法通关村——位运算常用技巧》

《算法通关村——位运算常用技巧》 位运算的性质有很多&#xff0c;此处列举一些常见性质&#xff0c;假设以下出现的变量都是有符号整数。 ●幂等律&#xff1a;a &aa&#xff0c;a ∣ aa&#xff08;注意异或不满足幂等律&#xff09;&#xff1b; ●交换律&#xff1…

基于Python实现连锁咖啡店经营情况EDA分析【500010097】

导入模块 import pandas as pd import plotly.graph_objects as go from plotly.subplots import make_subplots import plotly.express as px获取数据 df pd.read_csv(r./data/coffeeshop.csv) data_exploration(df)数据缺失值情况 print(数据缺失值情况&#xff1a;) df.…

【halcon】外观检测总结之灰度操作

1 灰度操作之 滞后延时 *滞后阈值 hysteresis_threshold (ImageInvert, RegionHysteresis, 190, 220, 3)这句话的意思就是&#xff0c;逐个判断这个图片区域里像素的灰度值&#xff0c;如果这个值小于190就不考虑了pass掉&#xff0c;如果大于220就直接入选。值在190和220之间…