【Maximal Rectangle】cpp
题目:
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
代码:
class Solution {
public:
int maximalRectangle(vector<vector<char> >& matrix)
{
if (matrix.empty()) return ;
const int ROW = matrix.size();
const int COL = matrix[].size();
vector<int> height(COL,);
vector<int> l_most(COL,);
vector<int> r_most(COL,COL-);
int max_area = ;
for ( int i = ; i < ROW; ++i )
{
int l_curr = ;
int r_curr = COL-;
// calculate current row's height
for ( int j = ; j < COL; ++j )
{
height[j] = matrix[i][j]=='' ? height[j]+ : ;
}
// from left to right
for ( int j = ; j < COL; ++j )
{
if ( matrix[i][j]=='' )
{
l_most[j] = std::max(l_most[j], l_curr);
}
else
{
l_most[j] = ;
l_curr = j+;
}
}
// from right to left
for ( int j = COL-; j>=; --j )
{
if ( matrix[i][j]=='' )
{
r_most[j] = std::min(r_most[j], r_curr);
}
else
{
r_most[j] = COL-;
r_curr = j-;
}
}
// calculate area of rectangle
for ( int j = ; j<COL; ++j )
{
max_area = std::max(max_area, (r_most[j]-l_most[j]+)*height[j]);
}
}
return max_area;
}
};
tips:
学习了网上的O(m×n)时间复杂度的解法。
这道题的路子类似于http://www.cnblogs.com/xbf9xbf/p/4499450.html
总体的思路如下:
每次遍历一行的元素,以这一行作为X轴;模仿largest rectangle in histogram这道题
大体思路如下,需要对largest rectangle in histogram这道题有比较深刻的理解
a) 计算每个点的当前高度
b) 计算当前高度下每个点能往左推到哪个位置
c) 计算当前高度下每个点能往右推到哪个位置
d) 遍历以当前行作为X轴可能获得的最大面积
a)~d)走完所有行,就可以获得最大的矩形面积
思路实在精妙,详细记录下思考每个环节的过程:
a) 如何计算当前点的高度?
利用滚动数组技巧:height[j]记录的是到i-1行该列对应的高度;如果matrix[i][j]=='1',则height[j] += 1,即比上一行该列位置+1;如果matrix[i][j]=='0'则对于第i行来说,该列对应的高度就是0。这个道理比较直观,简单说就是滚动数组height[j]的更新原则是看高度能不能在新的一行续上。这种滚动数组技巧的好处在于只需要维护一个一维数组,否则需要维护二维数组,是dp过程的常用技巧。
b) c) 如何找每个点向左(右)能推到的最远的位置?
这个部分更是精妙,不仅利用了滚动数组的技巧,而且还充分利用了上一轮dp的结果。以b)为例分析,c)同理。
在此题的背景下,当前行的某列能向左推到哪要考虑如下几种情况:
1)高度是是0(即matrix[i][j]=='1'不成立):显然能推到最左侧即0的位置,不受上一行该列能向左推到哪的影响。
2)如果高度不是0(即matrix[i][j]=='1'成立),则这当前行该列能向左推到哪取决于左侧第一个不比它高的列在哪?
考虑一个问题:在matrix[i][j]=='1'的前提下,第i行的l_most[j]可不可能比第i-1行的l_most[j]还小(即还往左)?
显然,这是不可能的。因为第i行的j列已经把高度续上了,当且仅当第i行l_most[j]~j列的位置都满足高度续上的前提下,第i行的l_most[j]才可能等于第i-1行的l_most[j];一旦第i行l_most[j]~j有一个位置没有续上高度,那么第i行的l_most[j]就要比第i-1行的l_most[j]小了.
通过以上分析,在第i行j列已经把高度续上的前提下,能向左推到哪,关键取决于在j左边且最靠近j列没续上高度的列,是否影响到了l_most[j]~j。因此,维护一个l_curr,标记到当前列为止,续上高度的列最多可能向左推到哪。
所以,需要比较l_most[j]与l_curr的位置。如果遇上了高度为0的,则自动把l_curr+1;如果高度不为0的,判断l_curr是否影响到了l_most[j]
描述的比较绕口,但是客观上也就是这样了。
d) 计算可能的最大高度
这个就是个常规的dp,不再赘述了。注意一点就是(right-left+1)*height,这里是否“+1”取决于l_most和r_most的取值方式。
==============================================
第二次过这道题,思路记得比较清晰;具体操作上一些细节再熟练一下。
class Solution {
public:
int maximalRectangle(vector<vector<char> >& matrix)
{
int ret = ;
if ( matrix.empty() ) return ret;
vector<int> height(matrix[].size(), );
for ( int i=; i<matrix.size(); ++i )
{
// update height
for ( int j=; j<matrix[i].size(); ++j )
{
height[j] = matrix[i][j]=='' ? : height[j]+;
}
// update max area
ret = max(ret, Solution::maxArea(height));
}
return ret;
}
static int maxArea(vector<int>& height)
{
int ret = ;
height.push_back();
stack<int> sta;
for ( int i=; i<height.size(); ++i )
{
if ( sta.empty() || height[i]>height[sta.top()] )
{
sta.push(i);
continue;
}
while ( !sta.empty() && height[sta.top()]>=height[i] )
{
int tmp = sta.top();
sta.pop();
if ( sta.empty() )
{
ret = max( ret, i*height[tmp] );
}
else
{
ret = max(ret, (i-sta.top()-)*height[tmp] );
}
}
sta.push(i);
}
height.pop_back();
return ret;
}
};
【Maximal Rectangle】cpp的更多相关文章
- hdu 4739【位运算】.cpp
题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...
- Hdu 4734 【数位DP】.cpp
题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...
- 【Valid Sudoku】cpp
题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...
- 【Permutations II】cpp
题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...
- 【Subsets II】cpp
题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...
- 【Sort Colors】cpp
题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...
- 【Sort List】cpp
题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...
- 【Path Sum】cpp
题目: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up ...
- 【Symmetric Tree】cpp
题目: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). F ...
随机推荐
- form自动提交
在做项目中,例如b2b的由商城跳往卖家中心的后台,当他既有会员账号又是卖家的时候,让他登录了商城,就不需要卖家登录的时候,处理过程中可以用到form表单自动登录. 实现简单思路:可以再普通会员登录的地 ...
- Activiti20180624
1.工作流介绍 工作流(WorkFlow),是对工作流程及其各操作步骤之间业务规则的抽象.概括.描述.工作建模,即将工作流程中的工作如何前后组织在一起的逻辑和规则,在计算机中以恰当的模型进行表示并对其 ...
- 【Linux/Ubuntu学习 11】git查看某个文件的修改历史
有时候在比对代码时,看到某些改动,但不清楚这个改动的作者和原因,也不知道对应的BUG号,也就是说无从查到这些改动的具体原因了- [注]:某个文件的改动是有限次的,而且每次代码修改的提交都会有commi ...
- 跨平台移动开发phonegap/cordova 3.3全系列教程-结合asp.net/jqmboile
遠程app配置 把編譯後的www資料夾,復制到遠程地址(目錄結構不要改變), 例如:建議使用app-framework 1.加入jquery mobile1.4点击打开链接 2.加入app-frame ...
- 【Oracle】曾经的Oracle学习笔记(8-15)ER图,三大范式,数据库字典,视图,索引,序列
一.数据库建模 二.建表 三.数据库字典 四.DML语句 五.视图 六.索引 七.序列 八.DDL语句 Lesson 8 Overview of Data Modeling and Database ...
- 【来龙去脉系列】RSA算法原理
如果你问我,哪一种算法最重要? 我可能会回答"公钥加密算法". 因为它是计算机通信安全的基石,保证了加密数据不会被破解.你可以想象一下,信用卡交易被破解的后果. 进入正题之前,我先 ...
- 【Quartus错误】Internal Error: Sub-system: AMERGE
错误内容:Internal Error: Sub-system: AMERGE, File: /quartus/atm/amerge/amerge_kpt_op.cpp, Line: 220 解决方案 ...
- Mac下对PhpStorm主题的添加
大家都知道,作为一个PHPer,PhpStorm是圈内评价较高的一款IDE. 所以,为了有一个更加个性化的coding界面,我们有很多的主题可以使用. phpStorm自带了好几个主题,你可以通过以下 ...
- JavaScript_对象
1. 直接创建实例: //简单对象 var person1 = new Object(); person1.name = "Mike"; person1.age = 29; pe ...
- 小记:iOS 中一般对于 view 不依赖 model 的的两种代码书写形式
一. 前言 对于在 MVC 的定义中,view 层是不引用 model 层,view 和 model 是不相往来的 一般开发中,我们都写过 在自定义 view 中增加一个 model 的属性,外接直接 ...