前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 85. 最大矩形(DP/单调递增栈,难)

LeetCode 85. 最大矩形(DP/单调递增栈,难)

作者头像
Michael阿明
发布2020-07-13 16:09:42
5460
发布2020-07-13 16:09:42
举报

1. 题目

给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

代码语言:javascript
复制
示例:
输入:
[
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]
]
输出: 6

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

2. 解题

类似题目:

LeetCode 221. 最大正方形(DP)

LeetCode 84. 柱状图中最大的矩形(单调递增栈)

2.1 DP

参考官方的解题思路:

代码语言:javascript
复制
class Solution {
public:
    int maximalRectangle(vector<vector<char>>& mat) {
        if(mat.empty())
            return 0;
        int i, j, minL, maxR, maxarea = 0;
        int r = mat.size(), c = mat[0].size();
        vector<vector<int>> left(r,vector<int>(c,0));
        vector<vector<int>> right(r,vector<int>(c,c));
        vector<vector<int>> height(r,vector<int>(c,0));
        for(i = 0; i < r; i++) 
        {
            //填写left,相连的1,先到最高,然后最左侧的下标
            minL = 0;
            for(j = 1; j < c; j++)
            {
                if(i == 0)//第一行
                {
                    if(mat[i][j] == '1')
                    {
                        if(mat[i][j-1] == '0')
                            minL = j;//左边0,当前1,需要更新最左边的边界minL
                        left[i][j] = minL;
                    }
                }
                else//剩余行
                {
                    if(mat[i][j] == '1')
                    {
                        if(mat[i][j-1] == '0')
                            minL = j;
                        left[i][j] = max(minL,left[i-1][j]);//跟上面的行,比较,取大
                    }
                }
            }

            maxR = c;
            for(j = c-2; j >= 0; j--)
            {
                if(i == 0)//第一行
                {
                    if(mat[i][j] == '1')
                    {
                        if(mat[i][j+1] == '0')
                            maxR = j+1;//右边0,当前1,更新最右边的边界maxR
                        right[i][j] = maxR;
                    }
                }
                else//其余
                {
                    if(mat[i][j] == '1')
                    {
                        if(mat[i][j+1] == '0')
                            maxR = j+1;
                        right[i][j] = min(maxR,right[i-1][j]);//还要更上面的比较,取小
                    }
                }
            }

            for(j = 0; j < c; j++)
            {
                if(i == 0)//第一行
                {
                    if(mat[i][j] == '1')
                        height[i][j] = 1;
                }
                else//剩余
                {
                    if(mat[i][j] == '1')
                        height[i][j] = 1+height[i-1][j];
                }
            }

            for(j = 0; j < c; j++)
                maxarea = max(maxarea, (right[i][j]-left[i][j])*height[i][j]);
        }
        return maxarea;//返回最大面积
    }
};

例子的求解过程如下:

数组

代码语言:javascript
复制
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]

left

代码语言:javascript
复制
  [0  0  2  0  0]
  [0  0  2  2  2]
  [0  0  2  2  2]
  [0  0  0  3  0]

right

代码语言:javascript
复制
  [1  5  3  5  5]
  [1  5  3  5  5]
  [1  5  3  5  5]
  [1  5  5  4  5]

height

代码语言:javascript
复制
  [1  0  1  0  0]
  [2  0  2  1  1]
  [3  1  3  2  2]
  [4  0  0  3  0]

area

代码语言:javascript
复制
  [1  0  1  0  0]
  [2  0  2  3  3]
  [3  5  3  6  6]
  [4  0  0  3  0]

2.2 单调递增栈

  • 思路跟84题一致,行数变多了而已
代码语言:javascript
复制
class Solution {
public:
    int maximalRectangle(vector<vector<char>>& mat) {
        if(mat.empty())
            return 0;
        int i, j, hi, width, maxarea = 0, m = mat.size(), n = mat[0].size();
        vector<int> h(n+1, 0);
        for(i = 0; i < m; ++i)
        {
            stack<int> s;
            mat[i].push_back('0');//请看84题
            for(j = 0; j <= n; ++j)
            {
                h[j] = mat[i][j]=='1' ? h[j]+1 : 0;//根据前一行,得到当前行的高
                while(!s.empty() && h[s.top()] > h[j])
                {
                    hi = h[s.top()];
                    s.pop();
                    width = s.empty() ? j : j-s.top()-1;
                    maxarea = max(maxarea, hi*width);
                }
                s.push(j);
            }
        }
        return maxarea;
    }
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-02-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 题目
  • 2. 解题
    • 2.1 DP
      • 2.2 单调递增栈
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档