力扣84. 柱状图中最大的矩形

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

如果有不了解单调栈这个数据结构的同学,可以在B站上看几分钟的视频了解一下!

单调栈思想:

  1. 核心逻辑就是通过维护一个单调递增栈,在 O(n)的时间内高效找到每个柱子的左右边界。
  2. 单调栈的核心特性在于:当一个元素被弹出时,它的左右边界会同时被确定。
    1. 右边界的确定 :当我们遍历到第 i 个柱子时,如果发现它的高度小于 栈顶柱子的高度,说明栈顶柱子遇到了右边第一个比它矮的柱子。因此,第 i 个柱子的索引就是栈顶柱子的右边界
    2. 左边界的确定 :由于栈内元素是单调递增的,当栈顶柱子弹出后,新的栈顶柱子 就是它左边第一个比它矮的柱子。因此,新的栈顶索引就是它的左边界

最下面是我写的代码,我来讲解一下代码的思路:

  • 初始化一个空栈,用于存柱子的索引。

  • 从左到右遍历柱子数组:

    • 若当前柱子高度大于或等于栈顶柱子高度,直接将当前索进入栈(保持单调递增特性)。

    • 若当前柱子高度小于栈顶柱子高度,说明找到了栈顶元素的右边界。开始循环弹出栈顶元素并计算面积:

      • 弹出当前栈顶,记为 cur(这是要计算面积的柱子)。

      • 当前遍历到的索引 i 即为 cur 的右边界。

      • 弹出后新的栈顶索引即为 cur 的左边界。

      • 计算面积并更新最大值:area = heightcur × (i - stack_top - 1)。

    • 重复弹出过程,直到当前柱子高度不再小于栈顶高度,然后将当前索引入栈。

Go 复制代码
func largestRectangleArea(heights []int) int {
	ans := 0
	n := len(heights)
	
	// 创建新数组,前后各加一个 0 作为哨兵,避免栈空判断
	h := make([]int, n+2)
	copy(h[1:], heights)
	
	// st 存的是索引,把左哨兵的索引 0 放入栈中
	st := []int{0}
	
	for i := 1; i < len(h); i++ {
		// 当前高度小于栈顶高度时,说明找到了栈顶柱子的右边界
		for h[i] < h[st[len(st)-1]] {
			// 弹出栈顶作为当前要计算面积的柱子
			cur := st[len(st)-1]
			st = st[:len(st)-1]
			
			// 此时新的栈顶就是 cur 的左边界
			w := i - st[len(st)-1] - 1
			area := h[cur] * w
			
			if area > ans {
				ans = area
			}
		}
		// 当前索引入栈,保持栈内索引对应的高度单调递增
		st = append(st, i)
	}
	
	return ans
}
相关推荐
木木子2214 小时前
# 密码强度检测深度解析:正则表达式实时分析、多维度评分算法与可视化反馈
mysql·算法·华为·正则表达式·harmonyos
Sw1zzle17 小时前
算法入门(四):二叉树 - 递归遍历三件套
算法·leetcode
万法若空17 小时前
【算法-查找】查找算法
java·数据结构·算法
葫芦和十三17 小时前
图解 MongoDB 30|查询路由与广播查询:带片键定向,不带就广播
后端·mongodb·agent
海石17 小时前
子树怎么找?树的3种遍历方式来帮忙!
算法·leetcode
海石18 小时前
难度分 1588:思路 + 技巧 = AC
算法·leetcode
葫芦和十三18 小时前
图解 MongoDB 29|分片键陷阱:jumbo chunk、孤儿文档和写入热点
后端·mongodb·agent
进击的程序猿~18 小时前
Go Zero源码阅读1
后端·golang
2601_9615934219 小时前
Rust 开发环境配置繁琐?RustRover 开箱即用搞定编码调试
开发语言·后端·macos·rust
bulldozer19 小时前
写了个零依赖的 Go 版本管理器,curl | bash 完事
go