【算法修炼道路】最大矩形

该博客探讨了如何在给定的二维二进制矩阵中找到只包含1的最大矩形并计算其面积。通过示例解释了算法思路,包括记录每个点从右往左的最大宽度,计算不同高度下的最大宽度来确定矩形面积,最终找到最大面积的矩形。文章提供了C++实现的执行时间和内存消耗信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

85. 最大矩形

给定一个仅包含 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
  • 0 <= row, cols <= 200
  • matrix[i][j] 为 '0' 或 '1'

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximal-rectangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 


PS【预留空白填写题解】编辑与2020-12-29 00:57

以示例1为例:

矩阵的面积是x * y(长 * 宽)

首先记录每个点从右往左可以达到的最大宽度

10100
10123
12345
10010

得到宽度矩阵(称之为matrix)以后,我们就得到了每个格子的极限宽度,小于等于这个极限宽度的宽度都能取到

然后我们需要计算最大高度,高度和层数有关,每一个位置向上搜索,得到公共的最大宽度,即此层此列往上的所有格子最小的极限宽度,然后乘以对应的层数,就得到了面积。

最后不断搜索,得到最大面积即可。

以matrix[2][3]和matrix[2][4]为例:

matrix[2][3]:

        当高度为1的时候,最大宽度为4,面积1*4=4

        当高度为2的时候,最大宽度为2,面积2*2=4

        当高度为3的时候,最大宽度为0,面积为0

        所以matrix[2][3]这个点的最大面积为4

matrix[2][4]:

        当高度为1的时候,最大宽度为5,面积1*5=5

        当高度为2的时候,最大宽度为3,面积2*3=6

        当高度为3的时候,最大宽度为0,面积为0

        所以matrix[2][4]这个点的最大面积为6

...

...


class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {

        if (matrix.size() == 0) return 0;
        
        // 先初始化一个"宽度"矩阵,表示每一个格子当前可达到的最大宽度
        int m[matrix.size()][matrix[0].size()];
        for (int i=0;i<matrix.size(); ++i) {
            for (int j=0; j<matrix[i].size(); ++j) {
                m[i][j] = 0;
                if (j == 0) {
                    if (matrix[i][j] == '0') m[i][j] = 0;
                    else m[i][j] = 1;
                }
                else {
                    if (matrix[i][j] == '0' ) m[i][j] = 0;
                    else m[i][j] = 1 + m[i][j-1];
                }
            }
        }
        // 遍历宽度矩阵,往上搜索,找到每一个最大高度,然后相乘,即得到最大面积
        int maxSize = 0;
        for (int i=0; i<matrix.size(); ++i) {
            for (int j=0; j<matrix[i].size(); ++j) {
                int minWidth = INT_MAX;
                for (int k=1; k<i+2; ++k) {
                    if (m[i+1-k][j] == 0) break;
                    else {
                        minWidth = min(minWidth, m[i+1-k][j]);
                        maxSize = maxSize > (minWidth * k) ? maxSize : minWidth * k;
                    }
                }
            }
        }

        return maxSize;
    }
};

 

执行用时:52 ms, 在所有 C++ 提交中击败了94.35%的用户

内存消耗:11.2 MB, 在所有 C++ 提交中击败了87.72%的用户

提交了3次,基本都在90%左右

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值