Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.
Example:
Input: [ ["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"] ] Output: 6
求矩阵中最大矩形面积。
这里介绍两个时间复杂度为O(n2)的解法
解法1 --维护动态栈
设矩阵大小为 n*m
方法类似于上篇的博客,只不过相当于进行了n次求解过程,每次的高度为连续'1'的长度
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
if(matrix.empty()||matrix[0].empty()) return 0;
int mx=INT_MIN;
vector<int> heights(matrix[0].size(),0);
for(int i=0;i<matrix.size();i++)
{
stack<int> record;int j=0;
for(;j<matrix[0].size();j++)
{
if(matrix[i][j]=='1')
{
heights[j]++;
}
else heights[j]=0;
while(!record.empty()&&heights[record.top()]>heights[j])
{
int c=heights[record.top()];
record.pop();
c=record.empty()? j*c:(j-record.top()-1)*c;
mx=c>mx?c:mx;
}
record.push(j);
}
while(!record.empty())
{
int c=heights[record.top()];
record.pop();
c=record.empty()? j*c:(j-record.top()-1)*c;
mx=c>mx?c:mx;
}
}
return mx;
}
};
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
解法2 --动态规划
height还是解法1中的高度
left right分别代表该元素的左右边界
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
if (matrix.empty()) return 0;
int m = matrix.size(), n = matrix[0].size();
int left[n]{}, right[n], height[n]{};
fill_n(right, n, n);
int ans = 0;
for (int i = 0; i < m; ++i) {
int left_t = 0, right_t = n;
for (int j = 0; j < n; ++j) {
if (matrix[i][j] == '1') {
++height[j];
left[j] = max(left_t, left[j]);
}
else {
height[j] = 0;
left[j] = 0;
left_t = j+1;
}
}
for (int j = n-1; j>= 0; --j) {
if (matrix[i][j] == '1') right[j] = min(right[j], right_t);
else {
right[j] = n;
right_t = j;
}
}
for (int j = 0; j < n; ++j)
ans = max(ans, height[j] * (right[j] - left[j]));
}
return ans;
}
};