IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode 热题 HOT 100 第36天:“最大矩形” -> 正文阅读

[数据结构与算法]LeetCode 热题 HOT 100 第36天:“最大矩形”

继续刷LeetCode 热题 HOT 100 的题目,并且在博客更新我的solutions。在csdn博客中我会尽量用文字解释清楚,相关Java代码大家可以前往我的个人博客jinhuaiyu.com中查看。
题目:最大矩形
给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例 1:
在这里插入图片描述
输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:6
解释:最大矩形如上图所示。
示例 2:
输入:matrix = []
输出:0
示例 3:
输入:matrix = [[“0”]]
输出:0
示例 4:
输入:matrix = [[“1”]]
输出:1
示例 5:
输入:matrix = [[“0”,“0”]]
输出:0
提示:
rows == matrix.length
cols == matrix[0].length
1 <= row, cols <= 200
matrix[i][j] 为 ‘0’ 或 ‘1’

solution 1:使用柱状图的优化思路
我们首先要想到怎么讨论所有可能是最大矩形的矩形(当然全部讨论也包括在内),一个简单的方法就是讨论任意两个位置作为左上角和右下角,能否组成矩形,如果能,面积是不是更大。但这样时间复杂度过高。进一步的,如果我们只讨论每个位置作为右下角,能得到的最大矩形,然后取其中最大的面积,有可能能降低一些复杂度。
一个位置作为右下角能得到的最大矩形,和它左侧有多少个连续1(包括自己得是1),以及正上方(同一列)所有位置的左侧分别有多少个连续1(包括自身)有关。
我们首先计算出矩阵的每个元素的左边连续 1的数量,使用二维数组 left 记录,其中left[i][j] 为矩阵第 i 行第 j 列元素的左边连续 1的数量。这个过程的时间复杂度为O(mn)(利用一定动态规划的思想,可以在遍历的同时计算当前位置的left,如果当前位置是0,那left肯定是0,如果当前位置是1,则left为其左侧点的left+1,每行第一个点特殊处理)。
当考察以matrix[i][j] 为右下角的矩形时,我们从下到上依次讨论该位置正上方所有位置作为右上角的情况,当讨论到matrix[k][j] 时(0<=k<=i),能得到最大的矩形宽度为left[i][j],left[i?1][j],…,left[k][j]中最小值。
在这里插入图片描述
如图所示,假设我们现在讨论黄色位置为右下角的情况,每个位置中的数字是其对应的left(包括自身在内左侧连续的1的个数)。向上讨论同一列的每个位置matrix[k][j]作为右上角的最大矩形,当k=i时,最大矩形高为1,宽为matrix[i][j]对应的left,即3,则最大矩形面积为3。当k=i-1时,最大矩形高位2,宽为matrix[i][j]对应的left和matrix[i-1][j]对应的left中的较小者,3比4小,所以最大矩形的宽为3,最大面积为2×3=6。依此类推直到讨论完黄色位置正上方所有位置作为右上角时的最大矩形……其实,如果在某个位置碰到0后,就没有必要再讨论更上方的位置作为右上角的情况了,因为接下来的left最小值永远是0,最大面积也是0。
对每个点重复上面的过程,可以得到全局的最大矩形。枚举每个点需要O(mn)时间复杂度,讨论每个点作为右下角时的最大矩形,需要讨论其上方所有点作为右上角的最大矩形,这个过程需要O(m)的时间复杂度。总的时间复杂度是O(m2n)。

solution 2:单调栈
我们来看讨论每个位置作为右下角时最大矩形的情况:
在这里插入图片描述
如图所示,画出来的绿色格子是值为1的,也就是右下角位置及其正上方所有位置对应的left的直观体现。方法1是对每行的每个位置讨论它这一列的情况(该位置正上方),我们想要降低时间复杂度,可以直接一次讨论一整列,不必要求最下方的位置作为右下角,而是这一列任意两个位置组成右上角和右下角能得到的最大矩形。
这个意思就是假设上面的图最下面一行就是整个matrix的最后一行,而有数字(表示left)的这一列是matrix 中的某一列,我们如果能讨论出这个图中最大矩形,那么只需要对每一列都画出这种图,就可以讨论出全局最大矩形。
这个问题现在就退化成了leetcode的第84题(柱状图中最大矩形),大家可以回顾一下:http://jinhuaiyu.com/leetcode-largest-rectangle-in-histogram/
84题图(求其中最大矩形,如红色区域):在这里插入图片描述
84题的柱状图是横着的,我们这里是竖着的。之前我们用单调栈解决了84题,时间复杂度为O(m),列举每一列的时间复杂度为O(n),之前求二维数组left的时间复杂度为O(mn),因此总的时间复杂度为O(mn),可以看到,相比方法1,时间复杂度降低了。
怎么用单调栈求矩阵每一列对应的柱状图中的最大矩形大家可以看看上面链接中84的解析,这道题的代码也会带有详细注释。

Finally,带有详细注释的代码放在我的个人博客http://jinhuaiyu.com/leetcode-maximal-rectangle/

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-24 15:33:08  更:2022-02-24 15:34:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:56:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码