题目
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.
For example, given the following matrix:
1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0Return 6.
分析
可以把本题看做是前文找最大矩形的变形,逐行去计算,把每行当做一个直方图计算当前的最大矩形面积,遇到矩阵中元素为0时,直方图该处的高度也要置为0,因为此时无法形成包含1的矩形;遇到矩阵中元素为1时,直方图该处的高度+1,每行都需要计算一遍最大矩形面积,代表矩阵遍历到该行出现的全部包含1的最大矩形,最后返回该值即可,另一种dp思想的方法参考:Share my DP solution 。
class Solution {
public:
int largestRectangleArea(vector<int> height) {
int ret = 0;
height.push_back(0);
vector<int> index;//index记录遇到的元素下标
for(int i = 0; i < height.size(); i++)
{
//当直方图高度不断增加时,一直向里面压入高度,一旦遇到下降,则在循环中计算当前高度之前围成的矩形最大面积,即index中比当前高度高或相等的都会弹出,用于计算之前的最大面积,而index中比当前高度小的保留下来,例如[2,5,6,7,3],由于最初压入一个0,变成[2,5,6,7,3,0],前4个直接压入index,遇到3时,计算[5,6,7]围成的最大面积,index中保留2的索引,最后遇到0,则计算[2,5,6,7,3]围成的最大面积
while(index.size() > 0 && height[index.back()] >= height[i])
{
int h = height[index.back()];
index.pop_back();
int sidx = index.size() > 0 ? index.back() : -1;
if(h * (i-sidx-1) > ret)
ret = h * (i-sidx-1);
}
index.push_back(i);
}
return ret;
}
int maximalRectangle(vector<vector<char>>& matrix) {
if(matrix.empty())
return 0;
int hSize=matrix[0].size();//保存当前行的直方图高度
vector<int> h(hSize+1,0);
int res=0;
for(int i=0;i<matrix.size();++i){//先得到当前行的直方图高度,然后调用直方图最大矩形面积的函数计算
for(int j=0;j<hSize;++j){
if(matrix[i][j]=='0')
h[j]=0;
else
h[j]+=1;
}
res=max(res,largestRectangleArea(h));//保留历史最大值
}
return res;
}
};