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

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

题目描述: 

解题思路:

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

具体步骤如下:

  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.kler.cn/a/292272.html

相关文章:

  • 【Vitepress报错】Error: [vitepress] 8 dead link(s) found.
  • 动态内存管理(c语言)
  • windows@多系统引导名字修改@默认引导系统修改@bcdedit配置
  • 恒流数显驱动数显LED驱动芯片VK16D32
  • opencv kdtree pcl kdtree 效率对比
  • 【Java Web】Ajax 介绍及 jQuery 实现
  • 深度解析Linux系统的基本概念及优缺点和原理
  • COD论文笔记 ECCV2024 Just a Hint: Point-Supervised Camouflaged Object Detection
  • 解决maven中阿里云镜像仓库无法下载源码的问题
  • 华为od统一考试B卷【密钥格式化】Java 实现
  • python多进程
  • 导入word模板的数据到DB,偏自学,可自改套用
  • eureka一
  • 如何给 Java 文件打成独立的 JAR 包
  • 最基本的SELECT...FROM结构
  • HTB-Funnel(ssh端口转发与Hydra爆破)
  • blast的快速安装使用-简易版
  • Python知识点:如何使用Slack与Python进行团队协作
  • C++的四种规范的类型转换
  • 广义回归神经网络(GRNN)
  • Facebook的AI进化:如何用智能技术提升内容推荐
  • DataAccessException产生原因及解决方案
  • One-Shot Imitation Learning
  • 谷歌计划在越南设立首个美国科技数据中心
  • 山东大学机试试题合集
  • 在 Ubuntu 上安装 Jenkins,并配置 SSH Server 插件