题目
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例
输入:
[
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]
]
输出: 6
思路
- 可以转化成84. 柱状图中最大的矩形的问题。
- 逐渐增加行数,去求最大矩阵的面积。创建一个数组heights表示当前各列的高度。更新规则是:
- 如果是二维数组第一行,则各列高度就是二维数组第一行的数字。
- 否则,如果当前行对应列的数字为0,则这一列的高度设为0。否则上一行的高度加1。
- 先算第一行最大矩阵面积。再算前两行…
代码
class Solution {
private:
int rows, cols;
public:
int maximalRectangle(vector<vector<char>>& matrix) {
if ( matrix.size() == 0 ) return 0;
int res = 0;
rows = matrix.size();
cols = matrix[0].size();
vector<int> heights( cols, 0 );
for ( int i = 0; i < rows; ++i ) {
for ( int j = 0; j < cols; ++j ) {
if ( i == 0 )
heights[j] = matrix[0][j] - '0';
else if ( matrix[i][j] == '0' )
heights[j] = 0;
else if ( matrix[i][j] == '1' )
heights[j] = heights[j] + matrix[i][j] - '0';
}
res = max( res, helper( heights ) );
}
return res;
}
int helper( vector<int>& heights ) {
int res = 0;
vector<int> left( cols, 0 );
vector<int> right( cols, 0 );
left[0] = -1;
for ( int i = 1; i < cols; ++i ) {
int j = i - 1;
while ( j >= 0 && heights[j] >= heights[i] )
j = left[j];
left[i] = j;
}
right[cols-1] = cols;
for ( int i = cols - 2; i >= 0; --i ) {
int j = i + 1;
while ( j < cols && heights[j] >= heights[i] )
j = right[j];
right[i] = j;
}
for ( int i = 0; i < cols; ++i )
res = max( res, ( right[i] - left[i] - 1) * heights[i] );
return res;
}
};