算法练习题14——leetcode84柱形图中最大的矩形(单调栈)

devtools/2024/11/9 15:03:03/

题目描述: 

解题思路:

要解决这个问题,我们需要找到每个柱子可以扩展的最大左右边界,然后计算以每个柱子为高度的最大矩形面积。

具体步骤如下:

  1. 计算每个柱子左侧最近的比当前柱子矮的位置

    • 使用一个单调栈(栈中保存元素索引)从左到右遍历柱子,确保栈中元素始终保持递增(从栈底到栈顶)。
    • 如果当前柱子的高度小于栈顶柱子的高度,则不断弹出栈顶元素,直到找到一个高度小于当前柱子的元素为止。
    • 这样可以确定每个柱子左边第一个比它矮的位置。
  2. 计算每个柱子右侧最近的比当前柱子矮的位置

    • 使用类似的单调栈方法,从右到左遍历柱子,确保栈中元素始终保持递增。
    • 同样地,可以确定每个柱子右边第一个比它矮的位置。
  3. 计算最大矩形面积

    • 计算每个柱子可以扩展的宽度,使用公式 (right[i] - left[i] - 1) * heights[i] 来计算以该柱子为高度的矩形面积。
    • 遍历所有柱子,找到最大面积。

代码示例: 

class Solution {public int largestRectangleArea(int[] heights) {int n = heights.length;int[] left = new int[n]; // 用于存储每个柱子的左边界int[] right = new int[n]; // 用于存储每个柱子的右边界Stack<Integer> stack = new Stack<>(); // 用于计算左右边界的单调栈// 从左到右遍历柱子,计算每个柱子左边第一个比它矮的位置for (int i = 0; i < n; i++) {// 如果栈不为空且栈顶柱子的高度大于等于当前柱子的高度,弹出栈顶元素while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {stack.pop();}// 如果栈为空,说明当前柱子左侧没有比它矮的柱子if (stack.isEmpty()) {left[i] = -1; // 左边界为-1} else {left[i] = stack.peek(); // 栈顶元素即为左边第一个比当前柱子矮的位置}// 将当前柱子的索引压入栈中stack.push(i);}stack.clear(); // 清空栈,用于计算右边界// 从右到左遍历柱子,计算每个柱子右边第一个比它矮的位置for (int i = n - 1; i >= 0; --i) {// 如果栈不为空且栈顶柱子的高度大于等于当前柱子的高度,弹出栈顶元素while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {stack.pop();}// 如果栈为空,说明当前柱子右侧没有比它矮的柱子if (stack.isEmpty()) {right[i] = n; // 右边界为n} else {right[i] = stack.peek(); // 栈顶元素即为右边第一个比当前柱子矮的位置}// 将当前柱子的索引压入栈中stack.push(i);}int ans = 0; // 用于存储最大矩形面积// 遍历每个柱子,计算以该柱子为高度的最大矩形面积for (int i = 0; i < n; i++) {// 以heights[i]为高度的矩形面积计算公式为:(right[i] - left[i] - 1) * heights[i]ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]);}return ans; // 返回最大矩形面积}
}

详细解题步骤:

  1. 初始化数组和栈

    • left[i] 存储柱子 i 左侧第一个比其矮的柱子的索引,如果不存在,设置为 -1
    • right[i] 存储柱子 i 右侧第一个比其矮的柱子的索引,如果不存在,设置为 n
    • 使用 Stack 存储柱子的索引,用于计算左右边界。
  2. 计算左边界

    • 遍历所有柱子:
      • 如果当前柱子的高度小于栈顶柱子的高度,弹出栈顶元素,直到找到一个高度小于当前柱子的元素。
      • 如果栈为空,说明当前柱子左侧没有比它矮的柱子,设置 left[i] = -1
      • 否则,设置 left[i] = stack.peek(),即栈顶元素是左边第一个比当前柱子矮的位置。
    • 将当前柱子的索引压入栈中。
  3. 计算右边界

    • 从右到左遍历所有柱子:
      • 使用类似的方法计算每个柱子右边第一个比它矮的位置。
  4. 计算最大矩形面积

    • 遍历所有柱子,以每个柱子作为最矮柱子,计算矩形的最大面积。
    • 使用公式 (right[i] - left[i] - 1) * heights[i] 来计算每个柱子的最大矩形面积。

http://www.ppmy.cn/devtools/107950.html

相关文章

【全网最全】《2024高教社杯/国赛》 B题 思路+代码+文献 优化算法+决策树 第一问 生产过程中的决策问题

领取压缩包 问题 1 建模思路 问题描述 企业需要购买零配件1和零配件2&#xff0c;供应商声称一批零配件&#xff08;零配件1或零配件2&#xff09;的次品率不超过某个标称值&#xff08;例如10%&#xff09;。企业希望通过抽样检测来决定是否接收这批零配件&#xff0c;同时希…

vue3+ts封装类似于微信消息的组件

组件代码如下&#xff1a; <template><div:class"[voice-message, { sent: isSent, received: !isSent }]":style"{ backgroundColor: backgroundColor }"click"togglePlayback"><!-- isSent为false在左侧&#xff0c;为true在右…

某云彩SRM2.0任意文件下载漏洞

文章目录 免责申明搜索语法漏洞描述漏洞复现修复建议 免责申明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 搜索语法 fofa icon_hash"1665918155"漏洞描述 某云采 SRM2.0是一款先…

优质的产业园都在怎么做运营?

产业园区作为区域经济发展的重要载体&#xff0c;其运营模式和管理水平直接影响着产业集聚的成效和区域经济的竞争力。在一线城市与新一线城市中&#xff0c;已经涌现出了一批以高效运营、创新服务为特色的优质产业园&#xff0c;今天&#xff0c;我们就城市标杆产业园的案例和…

学习之git分支

git分支 2.1 什么是分支 2.2 分支的好处 2.3 分支的操作 2.3.1 git branch -v 查看分支 2.3.2 git branch 分支名 创建分支 2.3.3 git checkout 分支名 切换分支 2.3.4 git merge 分支名 把指定的分支合并到当前分支上

经验笔记:NoSQL数据库及其缓存方法实践

NoSQL数据库及其缓存方法实践经验笔记 随着大数据时代的到来&#xff0c;传统的关系型数据库在处理大规模数据时面临诸多挑战&#xff0c;如扩展性不足、性能瓶颈等问题。NoSQL数据库因其在可扩展性、灵活性和性能方面的优势&#xff0c;逐渐成为解决这些问题的有效方案之一。…

prometheus基于文件的服务发现

之间讲到&#xff0c;prometheus监控的对象就来自于他的配置文件里面的targets&#xff0c;如果要新增被监控对象&#xff0c;就继续往targets里面加。 但这个缺点是&#xff0c;每次修改完后都得重启prometheus。有没有什么办法&#xff0c;能在不重启的情况下增加target呢&a…

MongoDB-Change Stream

Change Stream 指数据的变化事件流&#xff0c;MongoDB从3.6版本开始提供订阅数据变更的功能 是用于实现变更追踪的解决方案 Change Stream 的实现原理&#xff1a;是基于 oplog 实现的&#xff0c;提供推送实时增量的推送功能 它在 oplog 上开启一个 tailable cursor 来追踪所…