当前位置: 首页 > news >正文

河南省建设厅官方网站郭风春江西个人网站备案做论坛

河南省建设厅官方网站郭风春,江西个人网站备案做论坛,网站建设 广,国外精产品1688Problem: 84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 文章目录整体思路完整代码时空复杂度时间复杂度:O(N)空间…

Problem: 84. 柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。

文章目录

  • 整体思路
  • 完整代码
  • 时空复杂度
    • 时间复杂度:O(N)
    • 空间复杂度:O(N)

整体思路

这段代码旨在解决一个经典的、难度较高的问题:柱状图中最大的矩形 (Largest Rectangle in Histogram)。问题要求在一个由非负整数组成的数组(代表柱状图)中,找出能勾勒出的最大矩形的面积。

该算法采用了一种非常高效且标准的 单调栈 (Monotonic Stack) 解法。其核心思想是,对于每一个柱子 heights[i],如果我们能确定以它为最低高度的那个最大矩形的左右边界,我们就能计算出这个矩形的面积。全局的最大面积,必然是这些以每个柱子为最低高度的矩形面积中的最大值。

算法的整体思路可以分解为以下三个步骤:

  1. 第一步:为每个柱子找到其左侧第一个更矮的柱子

    • 算法使用一个单调栈(从栈底到栈顶,索引对应的柱子高度是单调递增的),并从左到右遍历 heights 数组。
    • 对于当前柱子 heights[i],它会不断地从栈顶弹出那些比它高或等高的柱子。
    • 当这个过程结束后,栈顶的柱子(如果存在)就是 i 左侧的第一个严格比 heights[i] 矮的柱子。这个柱子的索引被记录在 left[i] 中。如果栈为空,说明左侧没有比它更矮的柱子,我们将边界记为一个虚拟索引 -1
  2. 第二步:为每个柱子找到其右侧第一个更矮的柱子

    • 这个过程与第一步完全对称。
    • 算法清空单调栈,然后从右到左遍历 heights 数组。
    • 同样,对于当前柱子 heights[i],它会找到其右侧第一个严格更矮的柱子,并将其索引记录在 right[i] 中。如果右侧没有更矮的,边界记为虚拟索引 n(数组长度)。
  3. 第三步:计算最终结果

    • 现在,对于每一个柱子 i,我们已经知道了以它为最低高度的矩形的左右边界(分别是 left[i]right[i])。
    • 这个矩形的宽度可以被计算出来,即 width = right[i] - left[i] - 1
    • 其面积就是 area = heights[i] * width
    • 最后,算法遍历所有柱子,计算出以每个柱子为最低高度的矩形面积,并取其中的最大值作为最终答案。

这种方法通过两次线性扫描和单调栈,高效地为每个柱子找到了其作为矩形高度时的最大可能宽度,从而在线性时间内解决了问题。

完整代码

class Solution {/*** 计算给定柱状图中最大矩形的面积。* @param heights 代表柱状图中各个柱子高度的数组* @return 最大矩形的面积*/public int largestRectangleArea(int[] heights) {int n = heights.length;// st: 一个单调栈,用于存储柱子的索引。Deque<Integer> st = new ArrayDeque<>();// --- 步骤 1: 查找每个柱子左边第一个更矮的柱子 ---// left[i] 存储 heights[i] 左边第一个比它矮的柱子的索引int[] left = new int[n];for (int i = 0; i < n; i++) {int h = heights[i];// 维护单调递增栈:当栈不为空且栈顶柱子 >= 当前柱子时,弹出栈顶。while (!st.isEmpty() && h <= heights[st.peek()]) {st.pop();}// 此时栈顶即为左侧第一个更矮的柱子。如果栈为空,说明左侧没有更矮的。left[i] = st.isEmpty() ? -1 : st.peek();// 将当前柱子索引入栈st.push(i);}// --- 步骤 2: 查找每个柱子右边第一个更矮的柱子 ---// 清空栈以备复用st.clear();// right[i] 存储 heights[i] 右边第一个比它矮的柱子的索引int[] right = new int[n];for (int i = n - 1; i >= 0; i--) {int h = heights[i];// 同样维护单调递增栈(相对于遍历方向)while (!st.isEmpty() && h <= heights[st.peek()]) {st.pop();}// 此时栈顶即为右侧第一个更矮的柱子。如果栈为空,说明右侧没有更矮的。right[i] = st.isEmpty() ? n : st.peek();// 将当前柱子索引入栈st.push(i);}// --- 步骤 3: 计算最大面积 ---int ans = 0;for (int i = 0; i < n; i++) {// 对于每个柱子i,以它为最低高度的矩形面积为:// 高度: heights[i]// 宽度: 右边界 - 左边界 - 1,即 (right[i] - left[i] - 1)ans = Math.max(ans, heights[i] * (right[i] - left[i] - 1));}return ans;}
}

时空复杂度

时间复杂度:O(N)

  1. 第一遍扫描 (计算 left 数组):外层 for 循环遍历 N 次。内层的 while 循环虽然看起来可能导致复杂度升高,但由于每个元素的索引最多只会入栈一次、出栈一次,所以所有 pushpop 操作在整个循环中的总次数是 O(N)。因此,这部分的均摊时间复杂度为 O(N)
  2. 第二遍扫描 (计算 right 数组):与第一遍扫描的逻辑和分析完全相同,其时间复杂度也是 O(N)
  3. 第三遍扫描 (计算 ans):这是一个简单的 for 循环,遍历 N 次,每次执行 O(1) 的操作。时间复杂度为 O(N)

综合分析
算法的总时间复杂度是三次独立的线性扫描的和:O(N) + O(N) + O(N) = O(N)

空间复杂度:O(N)

  1. 主要存储开销:算法使用了两个辅助数组 leftright,以及一个栈 st
    • int[] left = new int[n]: 占用了 O(N) 的空间。
    • int[] right = new int[n]: 占用了 O(N) 的空间。
    • Deque<Integer> st: 在最坏的情况下(例如,一个严格递增的 heights 数组),栈需要存储所有 N 个索引。因此,栈的空间复杂度为 O(N)。
  2. 综合分析
    算法所需的额外辅助空间由 left 数组、right 数组和栈共同构成。总的空间复杂度为 O(N) + O(N) + O(N) = O(N)

参考灵神

http://www.dtcms.com/a/612369.html

相关文章:

  • 本地网站建设的步骤过程宣传平台
  • html做校园网站宁波网站开发服务
  • wordpress旅游网站wordpress+dns预读
  • 宿迁网站推广公司企业网站优化方案
  • 孟州网站百度收录提交接口
  • 中山中小企业网站制作google中文搜索引擎
  • 网站建设情况总结茶网站建设方案
  • 怎么提高自己网站的知名度巨人网络公司简介
  • 网站宣传用了最字网页设计基础实训计划
  • 手机网站建设开什么类型的票网站建设政务新媒体
  • 学做网站丛什么开始免费网上申请注册
  • 一个主机怎么做两个网站如何在网站投放广告
  • 云南建设厅和网站怎么做会员积分网站
  • 免费做网站哪里有平面设计专业哪个学校好
  • wordpress主题的网站模板一键优化ppt
  • 简述网站开发流程 旅游建筑网官网登录入口
  • 南京手机网站开发有没有能帮人快速网站备案的机构
  • 用什么自己做网站可以免费发布信息的网站有哪些
  • 网站logo是什么seo专业优化公司
  • 视频模板免费制作seo排名影响因素主要有
  • 上海外贸网站设计秦皇岛市建设局
  • 信仰类型的企业网站网站上传附件目录格式
  • 我想开个网站网站建设层级图
  • 网站域名以co与com有什么不同中国黄金集团建设有限公司网站
  • wordpress做x站主题龙岗网页设计
  • 国外网站建设现状图分析软件二次开发什么意思
  • 中国医院建设协会网站首页做网站每年都要费用的吗
  • 青浦网站设计制作建筑设计公司职位有哪些
  • 网站后台文字编辑器怎么做好推广和营销
  • 商业网站建设公司推荐太原网站优化常识