1、问题描述
给定一个只包含0、1的二进制二维矩阵,找出只包含1的最大矩形,并返回其最大面积。
示例:
输入:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
输出: 6
2、解题思路
思路1:暴力法。列举所有以为左上角和右下角顶点的矩形,取其中最大矩形的面积。
时间复杂度:,因为遍历所有的顶点两次,再加上遍历以这两个顶点为对角顶点的矩形面积有需要耗费时间。
空间复杂度:。
思路2:这道题其实和[leetcode - [栈] - 柱状图的最大矩形(84)]是一样的,它只不过是将其扩展为了二维的,不信看下图橙色部分:
因此,
(1)对于矩阵中第i行的每个元素,计算从上边界开始到连续的1的个数,并存储在矩阵中;
(2)中第行的值看成是柱状图的柱子的高度,求柱状图的最大矩形面积;
3、代码实现
/*算法思想:转换成求柱状图的最大矩形,如何转化?
(1)对于矩阵中第i行的每个元素matrix[i][j],计算从上边界开始到matrx[i][j]连续的1的个数,并存储在矩阵h[i][j]中;
(2)h中第i行的值看成是柱状图的柱子的高度,求柱状图的最大矩形面积;
*/
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
int rows = matrix.size();
int cols = rows > 0 ? matrix[0].size() : 0;
vector<vector<int>> h(rows, vector<int>(cols,0));
for(int c = 0; c < cols; c++){
for(int r = 0; r < rows; r++){
if(matrix[r][c] == '0'){
h[r][c] = 0;
}
else if(matrix[r][c] == '1'){
if(r > 0 && matrix[r-1][c] == '1'){
h[r][c] = h[r-1][c] + 1;
}
else{
h[r][c] = 1;
}
}
// cout<<"h["<<r<<"]["<<c<<"]="<<h[r][c]<<endl;
}
}
int area = 0;
for(int i = 0; i < rows; i++){
// cout<<"maxArea["<<i<<"]="<<maxArea(h[i])<<endl;
area = max(area, maxArea(h[i]));
}
return area;
}
int maxArea(vector<int>& height){
int len = height.size();
stack<int> s;
//压入height[0]的左边界索引;
s.push(-1);
int maxarea = 0;
for(int i = 0; i < len; i++){
while(s.top() != -1 && height[i] < height[s.top()]){
int top = s.top();
s.pop();
maxarea = max(maxarea, height[top] * (i - s.top() - 1));
}
s.push(i);
}
while(s.top() != -1){
int top = s.top();
s.pop();
maxarea = max(maxarea, height[top] * (len - s.top() - 1));
}
return maxarea;
}
};