Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >LeetCode 85 | 如何从矩阵当中找到数字围成的最大矩形的面积?

LeetCode 85 | 如何从矩阵当中找到数字围成的最大矩形的面积?

作者头像
TechFlow-承志
发布于 2020-07-14 08:00:51
发布于 2020-07-14 08:00:51
1.5K00
代码可运行
举报
文章被收录于专栏:TechFlowTechFlow
运行总次数:0
代码可运行

今天是LeetCode专题53篇文章,我们一起来看看LeetCode中的85题,Maximal Rectangle(最大面积矩形)。

今天的这道题目和上一篇文章讲的Largest Rectangle in Histogram这题有一定的相似,所以如果没有看过上一篇文章的同学,建议先移步观看一下上一篇。

LeetCode 84 | 单调栈解决最大矩形问题

85题的官方难度是Hard,点赞2757,反对69,通过率37.2%左右。它的情况和84题非常相似,点赞比很高,然后通过率也差不多。虽然它是84题的变形题,但是整体的题目质量还是很高的,没有因为这一点被诟病。那么和84题相比,究竟它的变动在哪里呢,让我们一起来看题目吧。

题意

给定一个只包含0和1的数字矩阵,要求在这个矩阵当中找到一个由1组成的最大面积的矩形,返回这个面积。

我们来看个样例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Input:
[
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]
]
Output: 6

答案是6,是这一块1围成的矩形:

题解

还是老规矩,我们从最简单的方法入手,一点点推导出最佳的思路。

暴力

首先最简单的当然是暴力,这题让我们寻找一个矩形,直接寻找矩形是有点麻烦的。计算机程序不像人眼,可以直接获取到图形相关的信息,计算机不行,只能获得单个位置的信息。所以我们让程序直接判断矩形是不现实的,但我们可以通过特征点来锁定矩形,这个也是业内常用的套路。

锁定一个矩形的方法一般有两种,第一种是用矩形的中心点和长宽来确定。这一种在各种图像识别和目标检测算法当中经常用到,模型预测的结果就是图像中心点的坐标以及长宽的长度。

第二种方法可以通过矩形的对角线上的两个点来确定,这种方法只适用于和坐标轴平行的矩形。比如下图当中,无论我们知道了(x2, y2), (x3, y3)还是(x1, y1), (x4, y4),我们都可以将这个矩形确定下来。

有了确定矩形的方法之后,我们通过暴力法来求解就简单了。我们通过这些值来枚举所有可能构成的矩形,然后依次遍历矩形中的每一个元素,来判断它们是否全是1,如果是否的话,那么就排除,否则则用来更新答案。

这种方法固然可行,但是估算一下,差不多应该是的规模,显然是我们不能接受的。

分析问题

在暴力解法当中我们遇到了时间复杂度的困难,我们想要优化就必须要解决复杂度的问题,复杂度的问题怎么解决呢?干想肯定是不行的,我们需要转变一下思路,寻找一下突破口。

我们枚举的复杂度规模这么高是因为我们遍历了所有矩形,遍历矩形本身就是一个时间复杂度开销非常大的举动。如果不想遍历矩形,还有什么方法可以得出最大面积呢?如果我们联想一下上一题很容易得出答案。

在上一题84题当中,题目给出的是一个个竖直类型的矩形,要求这些矩形组合当中能够找到的最大面积。

在这题当中我们可以对01的数字矩阵也做这么一个类似的变形,将从底部开始连续延伸的1的数量看成是竖直摆放的矩形的高度,这样我们这题就可以使用上一题的思路进行求解了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]

比如说上面这个矩阵就可以转变为[4, 0, 0, 3, 0],其实就是我们一列一列看,从最低处往上连续的1的数量。但是这样找到的面积最大值是4,并不是答案的6,原因是因为我们寻找的底层不对,并不一定以最后一行作为底面得到的面积最大。所以我们需要遍历作为底层的行,然后用这种方法寻找最大面积,全局当中找到的最大面积就是答案。

在上一题我们计算矩形面积的时候用到了两个单调栈,分别计算了某一个高度向左、向右能够延伸到的最远距离,其实这并没有必要。因为我们用一个栈也可以同时计算出两边的边界。举个例子:[1, 3, 6, 7],当前元素是5。我们需要把6,7出栈,5入栈。我们知道了5的左边界是3,但仔细想一想,对于7来说,我们知道了它的左右边界。7的左边界是6,右边界是5。也就是说对于栈顶的元素而言,它的左边界是stack[top-1],右边界是当前的位置i,宽就是i - stack[top-1] - 1。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution:
    def maximalRectangle(self, matrix: List[List[str]]) -> int:
        # 求出行数n和列数m
        n = len(matrix)
        if n == 0:
            return 0

        m = len(matrix[0])
  # 存储每一层的高度
        height = [0 for _ in range(m+1)]
        res = 0
        # 遍历以哪一层作为底层
        for i in range(n):
            sk = [-1]
            for j in range(m+1):
                # 计算j位置的高度,如果遇到0则置为0,否则递增
                h = 0 if j == m or matrix[i][j] == '0' else height[j] + 1
                height[j] = h
                # 单调栈维护长度
                while len(sk) > 1 and h < height[sk[-1]]:
                    res = max(res, (j-sk[-2]-1) * height[sk[-1]])
                    sk.pop()
                sk.append(j)
        return res

总结

乍一看这道题好像非常复杂,但是当我们对它进行分析和变形之后,它又变回了普通的单调栈的应用题。在单调栈的使用当中,有两个细节,一个细节是栈在初始化的时候插入了-1,插入-1是作为一个标兵,也就是所有情况能够达到的最左侧的边界。另一个细节是维护结束的时候插入了0,插入0的目的是为了弹出栈内所有的元素,因为只有出栈的元素会计算构成的面积,这样可以保证不会遗漏情况。

除了上面提到的之外,还有其他的一些细节,比如数组的创建的长度,还有矩形面积的计算公式等等。很多时候算法之所以难以实现,也正是因为需要考虑的细节很多,整体的逻辑不是非常清楚,需要我们进行大量的思考。总体来说,这是一道非常优秀的问题,值得大家仔细钻研。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder梁 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
​LeetCode刷题实战85: 最大矩形
https://leetcode-cn.com/problems/maximal-rectangle/
程序员小猿
2021/01/19
4280
​LeetCode刷题实战85: 最大矩形
Leetcode No.85 最大矩形(单调栈)
给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
week
2022/01/06
3070
Leetcode No.85 最大矩形(单调栈)
☆打卡算法☆LeetCode 85、最大矩形 算法解析
链接:85. 最大矩形 - 力扣(LeetCode) (leetcode-cn.com)
恬静的小魔龙
2022/08/07
5960
☆打卡算法☆LeetCode 85、最大矩形  算法解析
​LeetCode刷题实战84: 柱状图中最大的矩形
https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
程序员小猿
2021/01/19
4180
​LeetCode刷题实战84:  柱状图中最大的矩形
☆打卡算法☆LeetCode 84、柱状图中最大的矩形 算法解析
链接:84. 柱状图中最大的矩形 - 力扣(LeetCode) (leetcode-cn.com)
恬静的小魔龙
2022/08/07
2720
☆打卡算法☆LeetCode 84、柱状图中最大的矩形  算法解析
AcWing 1413. 矩形牛棚(每日一题)
约翰购买了一大块土地,这个土地可以看作是一个 R 行(编号 1∼R)C 列(编号 1∼C)的方格矩阵。
摆烂小白敲代码
2024/09/23
730
AcWing 1413. 矩形牛棚(每日一题)
力扣每日一刷(2023.9.24)
本题其实可以使用暴力解法实现的, 但是力扣的时间复杂度分析的有问题, O(n2)的时间复杂度尽然过不了。
用户11097514
2024/05/31
1140
力扣每日一刷(2023.9.24)
详解单调栈算法
如果你对这篇文章可感兴趣,可以点击「【访客必读 – 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。
全栈程序员站长
2022/11/09
6730
详解单调栈算法
用javascript分类刷leetcode13.单调栈(图文视频讲解)
我们怎样加速嵌套的这层循环呢,其实可以预先计算从左往右和从右往左的最大高度数组,在循环数组的时候,可以直接拿到该位置左右两边的最大高度,当前位置的接水量就是左右两边高度的较小者减去当前位置柱子的高度
js2030code
2023/01/05
5840
搞定大厂算法面试之leetcode精讲13.单调栈
搞定大厂算法面试之leetcode精讲13.单调栈 视频讲解(高效学习):点击学习 目录: 1.开篇介绍 2.时间空间复杂度 3.动态规划 4.贪心 5.二分查找 6.深度优先&广度优先 7.双指针 8.滑动窗口 9.位运算 10.递归&分治 11剪枝&回溯 12.堆 13.单调栈 14.排序算法 15.链表 16.set&map 17.栈 18.队列 19.数组 20.字符串 21.树 22.字典树 23.并查集 24.其他类型题 239. 滑动窗口最大值 (hard) 方法1.优先队列 动画过大,点击查
全栈潇晨
2021/12/01
7990
【LeetCode日记】84. 柱状图中最大的矩形
` 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
lucifer210
2020/03/12
4180
栈 使用案例总结
最近有几位球友问我,不知道怎么使用单调栈解决实际问题,今天我通过一道leetcode题目,来详细解读如何使用单调栈。
double
2021/03/30
6090
栈 使用案例总结
单调栈(C/C++)
单调队列和单调栈都是一种数据结构,应用十分广泛,在蓝桥杯、ICPC、CCPC等著名编程赛事都是重点的算法,今天博主将自己对单调栈与单调队列的理解以及刷题的经验,用一篇博客分享给大家,希望对大家有所帮助,它们用于解决类似“寻找最大值与最小值”这样的问题。它们的区别在于如何维护数据的单调性。、
摆烂小白敲代码
2024/09/23
900
单调栈(C/C++)
【LeetCode日记】85. 最大矩形
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
lucifer210
2020/03/12
6320
LeetCode 85. 最大矩形(DP/单调递增栈,难)
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
Michael阿明
2020/07/13
5860
【leetcode刷题】T22-柱状图中最大的矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
木又AI帮
2019/07/17
4150
【leetcode刷题】T22-柱状图中最大的矩形
算法细节系列(12):破除想当然
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/70820874
用户1147447
2019/05/26
3070
食堂店小二儿教你学会栈
店小二儿十分勤奋,前台后厨的活儿他都干,每天都要跑前跑后端顾客吃完的盘子。栈就像叠在一起的盘子,客人美滋滋的吃完饭,店小二去收拾桌子捡起盘子时,都是从下往上一个一个的放盘子。而他在后厨橱柜上取盘子给厨师时,是从上往下一个一个依次的取。
童欧巴
2020/09/10
3570
单调栈总结_进栈和出栈的算法思想
单调栈是一种特殊的栈,特殊之处在于栈内的元素都保持一个单调性。 假设下图是一个栈内元素的排列情况(单调递增的栈):
全栈程序员站长
2022/11/09
3270
单调栈总结_进栈和出栈的算法思想
单调栈巧解柱状图最大矩形
这几天群里打卡的几道题都是十分经典的面试题,经典是因为这些题都是一题多解的。在这些高效的解法中,单调栈是一个很有技巧的解法,所以这一次我们来聊聊这个单调栈。
TechFlow-承志
2020/03/06
1.6K0
相关推荐
​LeetCode刷题实战85: 最大矩形
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文