力扣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
}
相关推荐
Zane199411 小时前
两个线程算两遍循环,为什么只快了一点点不是两倍?GIL连环追问
后端·python
find1star11 小时前
LeetCode 25:K 个一组翻转链表
java·数据结构·算法·leetcode·链表·职场和发展·动态规划
只爱喝胡辣汤11 小时前
04-JVM 性能调优参数
后端
Bs_MoneyMagnet12 小时前
基于springboot+vue的家居生活商城平台的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring
爱勇宝12 小时前
《道德经》第 11 章:真正有用的,常常是你没写出来的那部分
前端·后端·产品
微三云 - 廖会灵 (私域系统开发)12 小时前
Spring Boot实战:五级分销定价与自动分佣系统设计与实现
java·spring boot·后端
王的宝库12 小时前
Gin + GORM
开发语言·golang·gin
钱栈up12 小时前
mvn compile卡住半小时:定位并修复隐藏的类型不匹配编译错误
java·后端·maven
妙码生花12 小时前
golang 应用服务端部署(使用 systemd 服务)
开发语言·人工智能·后端·golang·node.js·php·gin
Zane199412 小时前
Lambda表达式没有类型,为什么还能被当成参数传来传去
java·后端