代码随想录算法训练营Day60 | 84. 柱状图中最大的矩形

文章目录

  • 84. 柱状图中最大的矩形
    • 首尾加 0
    • 双指针

84. 柱状图中最大的矩形

题目链接 | 解题思路

本题和接雨水的题目相互呼应,但是难度略有提升,同样是一道非常棒的题!

在接雨水中,需要找到每一列的左侧最大值和右侧最大值;在本题中,需要找到每一列的左侧第一个更小值和右侧第一个更小值。这个要求的变化加大了双指针的难度,所以优先讨论更加适用的单调栈解法。

和上一题一样按行来计算矩形面积,对于固定的一列,需要这一列的高度、对应的左边界、对应的右边界。但这一题,单调栈的储存顺序发生了变化。

在这里插入图片描述

  1. 单调栈内的元素顺序、如何取值
    • 栈内元素应该是 top-bottom 递减的,此时向右搜索,找到当前元素大于栈口元素的时候就代表着找到了栈口元素这一列代表的高度的右边界
    • 当前元素大于栈口元素时:
      • 右边界即为当前元素
      • 基准位置即为栈口元素
      • 左边界即是栈口元素的内部相邻元素
  2. 当前元素与栈口元素相等:和接雨水的处理一样
    • 之所以能够对元素值相等的情况有多种处理,是因为在计算中只需要他们代表的值来作为基准高度,而不需要他们的确切下标,利用的下标是左边界和右边界。

对于当前元素与栈口元素的三种比较情况,也和接雨水中的方法无异。

首尾加 0

本题最大的不同就在于需要在输入数组的首尾各加入一个 0,从而解决一些特殊的输入数组:

  • 单调递增数组:heights = [2, 4, 6, 8]

    • 对这样的输入,每一步循环都会将当前下标压入栈。直到遍历结束,也不会有执行计算面积的操作,因为没有碰到一个更小的元素。所以在尾部加入一个 0,可以确保在这种情况下执行正确的面积计算。
  • 单调递减数组:heights = [8, 6, 4, 2]

    • 对这样的输入,每一步循环都会触发面积计算。然而,如上所述,面积的计算需要当前基准高度、左边界、右边界。对第二个下标 1 执行面积计算时,得到右边界 1,基准下标 0。弹出 0 后已经得到了一个空栈,无法得到左边界。所以,这种情况下也不会执行计算面积,因为总是不能得到左边界。
    • 所以在首部加入一个 0,可以确保在这种情况下执行正确的面积计算。

可以看到,在接雨水中我们没有特殊考虑过这两种情况。因为在接雨水中,如果不能够形成一个完整的谷,那么就不需要进行任何计算,也就是说单调递增、递减的数组本来就不该有任何计算结果。而在本题,任何输入都应该正确计算面积,所以不能只计算完整的峰,而要全面考虑。

class Solution:def largestRectangleArea(self, heights: List[int]) -> int:heights.insert(0, 0)heights.append(0)result = 0stack = [0]for i in range(1, len(heights)):if heights[i] > heights[stack[-1]]:stack.append(i)elif heights[i] == heights[stack[-1]]:stack.pop()stack.append(i)else:while (len(stack) > 0 and heights[i] < heights[stack[-1]]):mid = stack[-1]stack.pop()if len(stack) > 0:left = stack[-1]curr_width = i - left - 1curr_height = heights[mid]result = max(result, curr_height * curr_width)stack.append(i)return result

双指针

和接雨水一样,本题同样有双指针 + dp 的解法,但是这个解法的时间复杂度有些可疑。
和接雨水相比,本题中的双指针 + dp 会更加复杂一些,因为要求的不再是最大值而是第一个更小值的下标,dp 的递推变得很困难,我也不确定具体的复杂度。

这题的 dp 部分有点像是 KMP,感觉很有意思。

class Solution:def largestRectangleArea(self, heights: List[int]) -> int:# records the index of the first smaller value on the left of ileft_smaller_idx = [0] * len(heights) left_smaller_idx[0] = -1            # no smaller value on the left, representing non-existencefor i in range(1, len(heights)):temp = i - 1while (temp >= 0 and heights[temp] >= heights[i]):temp = left_smaller_idx[temp]left_smaller_idx[i] = temp# records the index of the first smaller value on the right of iright_smaller_idx = [0] * len(heights) right_smaller_idx[-1] = len(heights)            # no smaller value on the right, representing non-existencefor i in range(len(heights) - 2, -1, -1):temp = i + 1while (temp < len(heights) and heights[temp] >= heights[i]):temp = right_smaller_idx[temp]right_smaller_idx[i] = tempresult = 0for i in range(len(heights)):result = max(result, heights[i] * (right_smaller_idx[i] - left_smaller_idx[i] - 1))return result

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis基础知识(一)

Mybatis基础知识(一) Mybatis基础知识 Mybatis基础知识(一)一、MyBatis特性二、和其它持久化层技术对比三、MyBatis的简单使用1、创建maven工程2、创建pojo对象3、创建MyBatis的核心配置文件①properties②typeAliases③environments:④mappers:引入映射文件 4、创建mapper接口…

fabic如何将绘图原点移到画布中心

情况说明&#xff1a; fabic默认绘图原点为left&#xff1a;0&#xff0c;top&#xff1a;0 后端给我的内容是按照x&#xff0c;y返回的&#xff0c;需要将坐标系移到fabic画布的中心位置&#xff0c;找了下网上合适的砖&#xff0c;想一句命令直接设置&#xff0c;结果没有。…

C++QT day7

仿照vector手动实现自己的myVector&#xff0c;最主要实现二倍扩容功能 #include <iostream>using namespace std;template<typename T> class my_vector {int size;//可存储的容量大小int num;//当前存储的元素个数T* data;//存储数据的空间地址public://无参构造…

zabbix 钉钉微信企微告警(动作操作消息内容模板)

一、环境配置 1、配置zabbix服务端 2、配置监控主机&监控项&监控模板 zabbix配置安装_this page is used to test the proper operation of _疯飙的蜗牛的博客-CSDN博客 二、触发器 触发器的本质就是一个条件判断&#xff0c;对于不同的监控数据来说&#xff0c;我…

uniapp H5生成画布,插入网络图片。下载画布

因为网络图片不能直接使用ctx.drawImage(&#xff09;插入。得使用uni.getImageInfo()方法下载后插入。 但是当画布中存在多张网络图片时&#xff0c;必须等待uni.getImageInfo()下载完成后才行。这样得下载套下载。太过于繁琐。所以定义了一个递归下载方法。同时避免下载图片异…

k8s集群使用ingress转发grafana服务

文章目录 前言一、思路二、grafana准备1. grafana-configmap.yaml2. grafana.yaml 三、ingress准备1. ingress.yaml2. grafana-externalname.yaml3. ingress-nginx-controller 四、 本机host文件准备五、访问测试 前言 在k8s集群中&#xff0c;使用ingress服务转发grafana的页…

centos安装flink,通过windows访问webui

1. 安装flink 1.1. flink的下载 通过flink官网下载flink安装包 https://flink.apache.org/ 下载安装包 1.2 flink在centos上的安装 将下载好的flink-1.17.1-bin-scala_2.12.tgz安装包放到centos目录下 解压文件&#xff1a; [rootlocalhost ~]# tar -zxvf flink-1.17.…

利用Windows搭建Emby媒体库服务器,轻松实现无公网IP的远程访问

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

基于SpringBoot + Vue的项目整合WebSocket的入门教程

1、WebSocket简介 WebSocket是一种网络通信协议&#xff0c;可以在单个TCP连接上进行全双工通信。它于2011年被IETF定为标准RFC 6455&#xff0c;并由RFC7936进行补充规范。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性…

Python 基础知识结构

一、关键字 二、内置函数 三、运算符 1、算数运算符 加 数字与字符串拼接 - 减 * 乘 数字与字符串重复 / 除 返回浮点数 % 取模 返回除法的余数 奇偶判断 ** 幂次 // 整除 返回商的整数部分&#xff0c;向下取整数&#xff0c;注意&#xff1a;-10//3,出现负数时的情况只要参…

北斗+5G 织就精确定位的“天罗地网”

北斗卫星导航系统&#xff08;简称北斗系统&#xff09;是我国自主发展、独立运行的全球卫星导航系统&#xff0c;为全球用户提供全天候、全天时、高精度的定位、导航和授时服务。2020年7月31日&#xff0c;北斗三号系统建成开通并提供全球服务&#xff0c;北斗系统进入全面推广…

基于element-ui的年份范围选择器

基于element-ui的年份范围选择器 element-ui官方只有日期范围和月份范围选择器&#xff0c;根据需求场景需要&#xff0c;支持年份选择器&#xff0c;原本使用两个分开的年份选择器实现的&#xff0c;但是往往有些是不能接受的。在网上找了很多都没有合适的&#xff0c;所以打…

第3章_瑞萨MCU零基础入门系列教程之开发环境搭建与体验

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

Golang使用sqlx报错max_prepared_stmt_count超过16382

文章目录 背景mysql的预处理查看实例预处理详情com_stmt_prepare开启performance_schema 本地查看预处理语句 预处理语句飙升的原因生成预处理语句但是不close执行sql过程中发生错误 go服务分析抓包分析发送给mysql的包debug查看预处理细节sqlx发送statement command指令sqlx关…

第6章_瑞萨MCU零基础入门系列教程之串行通信接口(SCI)

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

Kafka3.0.0版本——消费者(Range分区分配策略以及再平衡)

目录 一、Range分区分配策略原理1.1、Range分区分配策略原理的示例一1.2、Range分区分配策略原理的示例二1.3、Range分区分配策略原理的示例注意事项 二、Range 分区分配策略代码案例2.1、创建带有4个分区的fiveTopic主题2.2、创建三个消费者 组成 消费者组2.3、创建生产者2.4、…

PowerShell脚本免杀/bypass/绕过杀毒软件,ReconFTW 漏洞扫描

PowerShell脚本免杀/bypass/绕过杀毒软件&#xff0c;ReconFTW 漏洞扫描。 #################### 免责声明&#xff1a;工具本身并无好坏&#xff0c;希望大家以遵守《网络安全法》相关法律为前提来使用该工具&#xff0c;支持研究学习&#xff0c;切勿用于非法犯罪活动&#…

STM32 FreeRTOS 内存问题

1. STM32L151C8T6 内存&#xff0c;64Kb 的Flash&#xff08;代码就是烧录在这里面的&#xff09;&#xff0c;16Kb 的RAM&#xff0c;程序跑起来之后的内存&#xff0c;相当于我们高考时发的草稿纸&#xff0c;直接影响程序的运行速度&#xff0c;可以用STM32 CubeMx 软件直接…

【Linux】常用工具(上)

Linux 常用工具 一、Linux 软件包管理器 yum1. 软件包2. 查看软件包3. 安装/卸载软件4. yum 其他指令的功能 二、Linux 编辑器 - vim 使用1. vim 的基本概念2. vim 的基本操作&#xff08;1&#xff09;光标移动&#xff08;命令模式&#xff09;&#xff08;2&#xff09;光标…

性能测试之压力测试

文章目录 一.基本介绍二.性能指标三.下载安装JMeter1.下载安装包2.启动JMeter 四.使用JMeter1.模拟用户请求2.填写测试地址3.接收测试结果4.结果解释 一.基本介绍 压力测试考察当前软硬件条件下系统所能承受的最大负荷并找到系统瓶颈所在。压测是为了系统在线上的处理能力和稳定…