leetcode[85] Maximal Rectangle
给定一个只含0和1的数组,求含1的最大矩形面积。
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
这样的题一般看来都是有O(n*m)的解法的。
借助上一题Largest Rectangle in Histogram 的解法。
我们现在把矩阵的每一行当做是上一题的问题,然后遍历所有的行数,取最大数就是解。
这里的每一行的高度怎么确定呢。
1.如果当前点为‘0’,那么高度就是0
2.如果当前点为‘1’,那么高度就是往上连续1的个数(包括自己)。
求高度是一个动态规划过程。用dp[i][j]来存某个位置的高度那么
对于第i行第j列的点:
if (matrix[i][j] == '1')
dp[i][j] = dp[i-1][j] + 1;
else
dp[i][j] = 0;
class Solution {
public:
//
int largestRectangleArea(vector<int> &height)
{
height.push_back();
int maxarea = ;
int i = ;
stack<int> stk;
while(i < height.size())
{
if (stk.empty() || height[stk.top()] < height[i])
{
stk.push(i++);
}
else
{
int t = stk.top();
stk.pop();
maxarea = max(maxarea, height[t]*(stk.empty()?i:i-stk.top()-));
}
}
return maxarea;
}
//
int maximalRectangle(vector<vector<char> > &matrix)
{
if (matrix.size() == || matrix[].size()==) return ;
int row = matrix.size(), col = matrix[].size(), ans = ;
vector<vector<int> > dp(row, vector<int>(col));
for (int j = ; j < col; j++)
dp[][j] = matrix[][j] - '';
for (int i = ; i < row; i++) //动态求每行的histogram高度
for (int j = ; j < col; j++)
{
if (matrix[i][j] == '')
dp[i][j] = dp[i-][j] + ;
else
dp[i][j] = ;
}
for (int i = ; i < row; i++)
{
ans = max(ans, largestRectangleArea(dp[i]));
}
return ans;
}
};
如上是O(n*m)的解法。其实我觉得这个大神的O(n^3)的解法解释也挺好理解。
分析:一般一个题目我首先会想想怎么暴力解决,比如这一题,可以枚举出所有的矩形,求出其中的面积最大者,那么怎么枚举呢,如果分别枚举矩形的宽度和高度,这样还得枚举矩形的位置,复杂度至少为O(n^4) (计算复杂度是我们把matrix的行、列长度都泛化为n,下同),我们可以枚举矩形左上角的位置,那么知道了矩形左上角的位置,怎么计算以某一点为左上角的矩形的最大面积呢?举例如下,下面的矩阵我们以(0,0)为矩形的左上角:
1 1 1 1 0 0
1 1 1 0 1 1
1 0 1 0 1 1
0 1 1 1 1 1
1 1 1 1 1 1
矩形高度是1时,宽度为第一行中从第一个位置起连续的1的个数,为4,面积为4 * 1 = 4
矩形高度是2时,第二行从第一个位置起连续1的个数是3,宽度为min(3,4) = 3,面积为3*2 = 6
矩形高度为3时,第三行从第一个位置起连续1的个数是1,宽度为min(1,3) = 1,面积为1*3 = 3
矩形高度为4时,第四行从第一个位置起连续1的个数是0,宽度为min(0,1) = 0,面积为0*4 = 0
后面的行就不用计算了,因为上一行计算的宽度是0,下面所有宽度都是0
因此以(0,0)为左上角的矩形的最大面积是6,计算以某一点为左上角的矩形的最大面积复杂度是O(n)。
注意到上面我们用到了信息“从某一行某个位置开始连续的1的个数”,这个我们可以通过动态规划求得:设dp[i][j]是从点(i,j)开始,这一行连续1的个数,动态规划方程如下:
- 初始条件:dp[i][column-1] = (matrix[i][column-1] == '1') (column是matrix的列数)
- dp[i][j] = (matrix[i][j] == '1') ? 1 + dp[i][j + 1] : 0 ,(从方程看出我们应该从每一行的后往前计算)
计算dp复杂度O(n^2),枚举左上角位置以及计算以该位置为左上角的矩形最大面积复杂度是O(n^2*n)=O(n^3),总的复杂度是O(n^3)
这个算法还可以优化,枚举到某个点时我们可以假设该点右下方全是1,得到一个假设最大面积,如果这个面积比当前计算好的面积还要小,该点就可以直接跳过;在上面计算以某点为左上角的矩形面积时,也可以剪枝,剪枝方法同上。具体可以参考代码注释。
class Solution {
public:
int maximalRectangle(vector<vector<char> > &matrix) {
int row = matrix.size();
if(row == )return ;
int column = matrix[].size();
int dp[row][column], res = ;
memset(dp, , sizeof(dp));
//求出所有的dp值
for(int i = ; i < row; i++)
dp[i][column-] = (matrix[i][column-] == '');
for(int i = ; i < row; i++)
for(int j = column - ; j >= ; j--)
if(matrix[i][j] == '')
dp[i][j] = + dp[i][j + ];
//以每个点作为矩形的左上角计算所得的最大矩形面积
for(int i = ; i < row; i++)
{
for(int j = ; j < column; j++)
{
//剪枝,column-j是最大宽度,row-i是最大高度
if((column - j) * (row - i) <= res)break;
int width = dp[i][j];
for(int k = i; k < row && width > ; k++)
{
//剪枝,row-i是以点(i,j)为左上角的矩形的最大高度
if(width * (row - i) <= res)break;
//计算以(i.j)为左上角,上下边缘是第i行和第k行的矩形面积
if(width > dp[k][j])width = dp[k][j];//矩形宽度要取从第i行到第k行宽度的最小值
res = max(res, width * (k - i + ));
}
}
}
return res;
}
};
leetcode[85] Maximal Rectangle的更多相关文章
- 求解最大矩形面积 — leetcode 85. Maximal Rectangle
之前切了道求解最大正方形的题,题解猛戳 这里.这道题 Maximal Rectangle 题意与之类似,但是解法完全不一样. 先来看这道题 Largest Rectangle in Histogram ...
- LeetCode (85): Maximal Rectangle [含84题分析]
链接: https://leetcode.com/problems/maximal-rectangle/ [描述] Given a 2D binary matrix filled with '0's ...
- [LeetCode] 85. Maximal Rectangle 最大矩形
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and ...
- leetCode 85.Maximal Rectangle (最大矩阵) 解题思路和方法
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and ...
- 85. Maximal Rectangle
85. Maximal Rectangle Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle c ...
- 刷题85. Maximal Rectangle
一.题目说明 题目,85. Maximal Rectangle,计算只包含1的最大矩阵的面积.难度是Hard! 二.我的解答 看到这个题目,我首先想到的是dp,用dp[i][j]表示第i行第j列元素向 ...
- 【LeetCode】85. Maximal Rectangle
Maximal Rectangle Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle conta ...
- 【leetcode】85. Maximal Rectangle(单调栈)
Given a rows x cols binary matrix filled with 0's and 1's, find the largest rectangle containing onl ...
- 【leetcode】Maximal Rectangle
Maximal Rectangle Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle conta ...
随机推荐
- 新的学生说说我是如何靠APP发展赢得了亿万
郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 14年踏入 ...
- java 正则表达式提取html纯文本
本文来自我的个人博客: java 正则表达式提取html纯文本 做内容的大家都知道,从html中直接提取纯文本是一个非常大的问题.现将我做的正则匹配贴上: import java.util.regex ...
- 网站的SEO以及它和站长工具的之间秘密(转)
博客迁移没有注意 URL 地址的变化,导致百度和 google 这两只爬虫引擎短时间内找不到路.近段时间研究了下国内最大搜索引擎百度和国际最大搜索引擎google的站长工具,说下感受. 百度的站长工具 ...
- 如何使用滑动菜单SlidingMenu?
左側滑: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvanVuaHVhaG91c2U=/font/5a6L5L2T/fontsize/400/fill/I ...
- springmvc集成Ueditor插件实现图片上传2、
一.下载Ueditor插件. 地址:http://ueditor.baidu.com/website/download.html 二.环境搭建. 具体可以参看http://fex.baidu.com/ ...
- contentWindow,
a>contentWindow 兼容各个浏览器,可取得子窗口的 window 对象.b>contentDocument Firefox 支持,> ie8 的ie支持.可取得子窗口的 ...
- IBM Java架构师的技能
一天,群里飘过一个IBM招聘信息.我看过之后,也只是如此而已. 大家好!我是XXX,IBM招聘java架构师,如今还有38个名额 学历大专以上即可,英语能面试交流的.项目有非常多到时候依据您面试会详谈 ...
- 第1章 单例模式(Single Pattern)
原文 第1章 单例模式(Single Pattern) 单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点. 一.常用模式: 1 ...
- html浏览器兼容性 JavaScript语法
1. 在FireFox中能够使用与HTML节点对象ID属性值同样的JS变量名称,可是IE中不行. 解决的方法:在命名上区分HTML节点对象ID属性值和JS变量 2. IE不支持JS ...
- mysql_SQL_按照日统计微博数
主要备忘: DATE_FORMAT 函数 1:微博对比图(按日统计) SELECT DATE_FORMAT(tw.article_publish_time, '%Y-%m-%d'),count(pag ...