【LeetCode热题100】打卡第26天:最大矩形

news2024/12/25 9:30:49

文章目录

  • 最大矩形
    • ⛅前言
    • 🔒题目
    • 🔑题解

最大矩形

⛅前言

大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。

LeetCode热题100专栏🚀:LeetCode热题100

Gitee地址📁:知识汲取者 (aghp) - Gitee.com

题目来源📢:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激

🔒题目

原题链接:85.最大矩形

image-20230620194956327

🔑题解

  • 解法一:往下扩展(以当前节点作为矩形的右上角)

    先构建一个sum数组(这个很重要),sum[i][j]表示第i行第j列的节点,从当前节点往左出现连续1的长度(也就是记录当前节点为矩形右上角的最大宽度),前言万语抵不过一张图,看完下面几张图我相信你能够明白的

    ①如下是matrix数组:

    image-20230623132929122

    ②构建sum数组(从左往右对出现连续1的节点进行自增操作):

    image-20230623133134582

    ③以当前节点为矩形的右上角,计算节点能构成矩形的最大面积

    例如,遍历第一个节点时,先以自生高度,然后往下枚举,高度加一

    image-20230623133641935

    ……

    例如,枚举第10个节点时,第一层的矩形直接是3,往下扩展,此时第二层的宽是5,第一层的宽是3,以最短的宽为准,所以此时矩形的面积是6,第三层的宽是0,所以第三层不能构成一个矩形,综上,节点10能组成矩形的最大面积是6

    image-20230623134501958

    /**
     * @author ghp
     * @title
     */
    class Solution {
        public int maximalRectangle(char[][] matrix) {
            int m = matrix.length;
            int n = matrix[0].length;
            // 构建sum数组
            int[][] sum = new int[m][n];
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (matrix[i][j] == '1') {
                        if (j == 0) {
                            sum[i][j] = 1;
                        } else {
                            sum[i][j] += sum[i][j - 1] + 1;
                        }
                    } else {
                        sum[i][j] = 0;
                    }
                }
            }
            int ans = 0;
            // 枚举每一个节点
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    int width = sum[i][j];
                    // 枚举当前节点下的所有行
                    for (int k = i; k < m; k++) {
                        // 当k=i时,是当前层的高度,所以需要+1
                        int height = k - i + 1;
                        // 选所有行中的最小宽度作为当前矩形的宽度
                        width = Math.min(width, sum[k][j]);
                        // 更新最大矩形的面积
                        ans = Math.max(ans, height * width);
                    }
                }
            }
            return ans;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( m ∗ n ) O(m*n) O(mn)

    其中 n n n 为数组中元素的个数

  • 解法二:往上扩展(以当前节点作为矩形的右下角)

    解法一,自上而下枚举,节点要枚举两遍,第一遍枚举构建sum数组,第二遍枚举计算节点能构成矩形的最大面积。我们可以换一种思路,自下而上枚举,在枚举节点构建sum数组的同时,还计算当前节点能构成矩形的最大面积,这样就能够省掉一遍枚举,虽然时间复杂度没有减小,但是节约了时间😄

    ①枚举第1个节点,得到矩形的最大面积是1:

    image-20230623134648987

    ……

    ②枚举10个节点,此时第10个节点的左边和上边的节点的和都计算了:

    遍历第10个节点所在当前层时,矩形的宽度是3,此时矩形的面积是3,往上扩展,上一层的宽度是0,所以此时矩形的面积是0。所以此时第10个节点能够成矩形的最大面积是3

    image-20230623134955443

    ③枚举第15个节点:

    当前层构成矩形的最大面积是5,往上扩展后,此时最小宽度变成了3,高度变成了2,构成矩形的最大面积是6,继续往上扩展……

    最终可以得到第15个节点能够构成矩形的最大面积是6

    image-20230623135258396

    /**
     * @author ghp
     * @title
     */
    class Solution {
        public int maximalRectangle(char[][] matrix) {
            int m = matrix.length;
            int n = matrix[0].length;
            int[][] sum = new int[m][n];
            int ans = 0;
            for (int i = 0; i < m; i++) {
                // 构建sum数组
                for (int j = 0; j < n; j++) {
                    if (matrix[i][j] == '1') {
                        if (j == 0) {
                            sum[i][j] = 1;
                        } else {
                            sum[i][j] += sum[i][j - 1] + 1;
                        }
                    } else {
                        sum[i][j] = 0;
                    }
                    int width = sum[i][j];
                    // 以当前节点为矩形的右下角,往上枚举
                    for (int k = i; k >= 0; k--) {
                        int height = i - k + 1;
                        // 选所有行中的最小宽度作为当前矩形的宽度
                        width = Math.min(width, sum[k][j]);
                        // 更新最大矩形的面积
                        ans = Math.max(ans, height * width);
                    }
                }
            }
            return ans;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( m ∗ n ) O(m*n) O(mn)

    其中 n n n 为数组中元素的个数

  • 解法三:思维转换

    我们要求一个 m ∗ n m*n mn的二维数组中,连续1组成的一个最大矩形面积,如果直接来暴力枚举,可能时间复杂度很高,我们可以换一种思路,把每一列连续的1看着一个柱子,我们只需要求相邻柱子构成的最大面积,这样恒容易就想到了84题

    PS:我是一路刷LeetCode热题100遇到这题的,并且是根据题号一路刷过来的,所以刚好(●’◡’●),但是这个思路我并没有想到🤣我还有待继续努力(ง •_•)ง

    温馨提示:如果你没有做过84题,建议先把84题写完再来写这一题,可能豁然开朗

    关于这题的具体思路,我相信看完下面这几张图,你应该会有所了解的:

    ①一层一层对二维数组matrix纵向求和

    image-20230622204744567

    ②得到sum数组(从上至下对连续出现1的节点进行自增操作):

    image-20230622205034701

    ③此时我们可以,把每一层(也就是每一行)看作一个地平线,这样就可以计算每一层相邻柱子能构成最大矩形的面积,当然还需要单独使用一个变量来记录当前全局最大矩形的面积

    第一层:最大面积是4

    image-20230622205914769

    第二层:最大面积是6

    image-20230622210131361

    第三层……

    最后通过迭代计算,可以得出martix数组中有连续1构成的矩形的最大面积是6,下面是题解代码:

    import java.util.ArrayDeque;
    import java.util.Deque;
    
    /**
     * @author ghp
     * @title
     */
    class Solution {
        public int maximalRectangle(char[][] matrix) {
            int m = matrix.length;
            int n = matrix[0].length;
            // 构建sum数组
            int[][] sum = new int[m + 1][n + 1];
            for (int i = 1; i <= m; i++) {
                for (int j = 1; j <= n; j++) {
                    sum[i][j] = matrix[i - 1][j - 1] == '0' ? 0 : sum[i - 1][j] + 1;
                }
            }
            // 遍历每一层的柱子,更新max
            int max = Integer.MIN_VALUE;
            for (int i = 1; i <= m; i++) {
                // 这里就可以直接调用 【84.柱状图中最大的矩形】 的方法了
                max = Math.max(max, largestRectangleArea(sum[i]));
            }
            return max;
        }
    
        public int largestRectangleArea(int[] heights) {
            // 创建一个临时数组,前0用于计算第一个柱子的面积,后一个0用于强制出栈(这一步超级重要)
            int[] tempArr = new int[heights.length + 2];
            for (int i = 1; i < heights.length + 1; i++) {
                tempArr[i] = heights[i - 1];
            }
            // 递增栈(栈中存储柱子的索引号,栈中的柱子的高度严格递增)
            Deque<Integer> stack = new ArrayDeque<>();
            int ans = 0;
            // 枚举当前层所有的柱子
            for (int i = 0; i < tempArr.length; i++) {
                while (!stack.isEmpty() && tempArr[i] < tempArr[stack.peek()]) {
                    // 当前柱子比上一个柱子的高度要矮,不符合单调递增栈的要求,停止入栈
                    // 计算最上一个柱子能构成最大矩形的面积
                    int index = stack.poll();
                    ans = Math.max(ans, (i - stack.peek() - 1) * tempArr[index]);
                }
                stack.push(i);
            }
            return ans;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ∗ m ) O(n*m) O(nm)
    • 空间复杂度: O ( n ∗ m ) O(n*m) O(nm)

    其中 n n n 为matrix数组的列, m m m为matrix数组的行

PS:这里关于【84.柱状图中最大的矩形】的题解,可以参考这篇文章

【LeetCode热题100】打卡第25天:柱状图中最大的矩形_知识汲取者的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/677731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

随着ChatGPT、文言一心的大火,未来可能的生活工作方式

前面的文章笼统的扯了一些ChatGPT、文言一心的差异化&#xff0c;感觉还是不够明白直观。特地找了一份资料&#xff0c;通过基础能力、进阶能力、和一些垂直领域的几百个各种问题&#xff0c;来对比分析两者的回答情况&#xff0c;让大家可以有个更接地气的了解。 由于问题太多…

无限脉动:释放音乐和区块链在音乐领域的力量

音乐是一种永恒的通用语言&#xff0c;它将人们聚集在一起&#xff0c;超越了边界&#xff0c;在我们灵魂深处产生共鸣&#xff0c;创造联系。在当今数字时代&#xff0c;随着区块链技术和去中心化网络的出现&#xff0c;音乐世界正在经历一场深刻的变革。 我们在与艺术家合作&…

动态规划 DP (二)

3.二维动态规划 1) 力扣https://leetcode.cn/problems/minimum-path-sum/第一行的的路径只与左边的元素有关&#xff0c;第一列的路径只与上面的元素有关。 除了第一行和第一列&#xff0c;其他元素的路径取决于左边和上面元素的最小值。 只要每次都选择值最小的路径&#…

2021电工杯数学建模B题解题思路(光伏建筑一体化板块指数发展趋势分析及预测)

目录 一、前言 二、问题背景 三、具体问题 四、解题思路 &#xff08;一&#xff09;整体思路 &#xff08;二&#xff09;问题一 &#xff08;三&#xff09;问题二 &#xff08;四&#xff09;问题三 &#xff08;五&#xff09;问题四 &#xff08;六&#xff09;…

2023最新谷粒商城笔记之秒杀服务篇(全文总共13万字,超详细)

秒杀服务 秒杀具有瞬间高并发的特点&#xff0c;针对这一特点&#xff0c;必须要做限流异步缓存(页面静态化)独立部署 限流方式&#xff1a; 前端限流&#xff0c;一些高并发的网站直接在前端页面开始限流&#xff0c;例如&#xff1a;小米的验证码设计Nginx 限流&#xff0c…

ChatGPT从入门到精通,深入认识Prompt

ChatGPT从入门到精通&#xff0c;一站式掌握办公自动化/爬虫/数据分析和可视化图表制作 全面AI时代就在转角 道路已经铺好了 “局外人”or“先行者” 就在此刻 等你决定让ChatGPT帮你高效实现职场办公&#xff01;行动起来吧1、ChatGPT从入门到精通&#xff0c;一站式掌握办公…

Unity 中的旋转、targetFrameRate、 vSyncCount、Time

1. 旋转&#xff1a; Unity 中的旋转用eulerAngle 表示&#xff0c;但在内部是以quaternion存储。欧拉角旋转围绕三个轴进行三次独立旋转&#xff0c;依次是z、x、y。To convert from Euler angles to quaternions, you can use the Quaternion.Euler function.To convert a q…

Linux 文件操作

文章目录 一、task_struct 和 file 的关系二、文件操作的系统调用三、进程默认打开的三个文件四、文件重定向五、Linux 下一切皆文件 文件是在磁盘上创建出来的&#xff0c;当我们想进行文件操作时&#xff0c;根据冯诺依曼体系结构&#xff0c;CPU 只和内存交互&#xff0c;为…

【裸机开发】Reset 中断服务函数(汇编实现)

目录 一、Reset 中断服务函数的实现步骤 二、汇编实现 Reset 中断服务函数 1、禁止/打开全局中断 2、设置SP指针 3、清除 .bss 段 4、完整 Reset 中断服务函数 一、Reset 中断服务函数的实现步骤 实现 Reset 中断服务函数的基本步骤如下&#xff1a; 设置各个模式下的S…

关联式容器set和map

文章目录 一.容器二.set的介绍1.insert2.lower_bound&&upper_bound3.find和countfindcount 三. multiset四.map最特别的operator[] 四.multimap&#xff0c;因为允许键值冗余&#xff0c;所以它没有operator[]&#xff0c;它的find返回的是中序遍历第一次遇到的节点五.…

ChatGPT办公自动化实战

ChatGPT从入门到精通&#xff0c;一站式掌握办公自动化/爬虫/数据分析和可视化图表制作 全面AI时代就在转角 道路已经铺好了 “局外人”or“先行者” 就在此刻 等你决定 让ChatGPT帮你高效实现职场办公&#xff01;行动起来吧 1、ChatGPT从入门到精通&#xff0c;一站式掌握办…

对象的销毁

析构函数 C 中的类可以定义一个特殊的清理函数 这个特殊的清理函数叫做析构函数析构函数的功能与构造函数相反 定义&#xff1a;~ClassName() 析构函数没有参数也没有返回值类型声明析构函数在对象销毁时自动被调用 析构函数使用初探 #include <stdio.h>class Test …

Threadlocal 必会的9个知识点

1.什么是ThreadLocal&#xff1f;它在多线程环境下有什么用处&#xff1f; ThreadLocal是在多线程环境下提供的一种简单的机制&#xff0c;使得每个线程都能拥有一个独立的变量副本。它避免了线程安全问题&#xff0c;并提高了程序的并发性能。 2.ThreadLocal是如何工作的&am…

规则引擎--规则逻辑形如“1 (2 | 3)“的抽象设计

目录 规则下逻辑表达和条件的抽象表达逻辑的编码和抽象 规则规则下的条件操作符抽象定义规则类规则执行表达式遍历进行操作符计算添加规则下一个具体条件的执行 规则执行完成后得到最后的结果 规则下逻辑表达和条件的抽象 对于任何一个规则&#xff0c;当然包括多个条件&#…

市面上最强PDF:GcPDF 6.1.4 Grapecity -Crack

适用于 .NET 6 的功能丰富的 PDF API 库 完全控制 PDF - 快速生成文档、提高内存效率且无依赖性。 在代码中生成、加载、编辑和保存 PDF 文档 支持多种语言的全文、段落格式和字体 使用新的编辑工具编辑 PDF 中的内容 支持数百种PDF功能 Windows、macOS 和 Linux 完全支持所有…

PhotoShop Beta(爱国版)安装教程-内置AI绘画功能

PS beta版安装教程 Window和Mac版都有&#xff0c;里面内置AI绘画功能 ps Beta版真的太爽了&#xff0c;今天来和大家分享下安装教程。 很多人拿这资料卖5块 9.9 19.9&#xff0c;球友们直接用&#xff0c;建议赶紧装&#xff0c;以免PS更新后&#xff0c;很多pojie程序没法用了…

ChatGPT数据分析与可视化实战

ChatGPT从入门到精通&#xff0c;一站式掌握办公自动化/爬虫/数据分析和可视化图表制作 全面AI时代就在转角 道路已经铺好了 “局外人”or“先行者” 就在此刻 等你决定 让ChatGPT帮你高效实现职场办公&#xff01;行动起来吧1、ChatGPT从入门到精通&#xff0c;一站式掌握办…

docker安装drone

目录 Drone简介docker安装drone创建Drone-server容器创建Drone-runner-docker容器 访问drone-server面板操作 Drone简介 Drone是基于GO语言开发的持续集成&#xff08;Continuous integration&#xff0c;CI&#xff09;引擎&#xff0c;它可以借助Docker容器技术&#xff0c;…

Autosar RTE C/S接口实现及synchronous与asynchronous的区别

文章目录 前言Server接口设计server接口Simulink实现server函数mapping Function生成的代码 Client接口设计Client接口Simulink实现ClientFunction Caller Mapping生成的代码Rte_CallRte_Result 总结 前言 在之前的一篇文章中&#xff0c;介绍了RTE中的S/R接口&#xff0c;也是…

(一)WPF - WPF

一、Window 图形演化 创建用户界面&#xff1a; User32&#xff1a; 该部分为许多元素&#xff08;如窗口、按钮和文本框等&#xff09;提供了熟悉的 Windows 外观。GDI/GDI&#xff1a; 该部分为渲染简单形状、文本以及图像提供了绘图支持&#xff0c;但增加了复杂程度&…