- 示例:
- 思路:动态规划
https://blog.csdn.net/maxiaotiaoti/article/details/62230381
定义概念,初始化边界,一般递推
cur_left当前元素可以延伸到最左边元素的下标。当元素为0时,cur_left取0。
cur_right为当前元素可以延伸到最右边元素的下标加1.当前元素为1时,cur_right取n数组长度。
总结:cur_left和cur_right均有当前行的值来决定,当前值为1,则cur_left和cur_right均不变;如果当前值为0,则cur_left值为当前元素右侧,cur_right值为当前元素位置(左闭右开)
left[i][j]定义ij处,可延伸到最左边元素的下标
right[i][j]定义ij处,可延伸到最右边元素的下标加1
核心思路时一行一行处理,使ij处最大矩阵的面积为(right[i][j]-left[i][j]*height[i][j]),height统计当前位置及往上1的数量;left和right使height的左右边界,即以当前点为中心,以height为高度向两边扩散的左右边界。
left[i][j]=max(left(i-1,j),cur_left)
right[i][j]=min(right(i-1,j),cur_right)
if m[i][j]==1 height[i][j]=height[i-1][j]+1;
if m[i][j]==0 height[i][j]=0. - 代码(动态规划)
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
if(matrix.empty())
return 0;
int m=matrix.size();
int n=matrix[0].size();
int res=0;
vector<int> left(n,0);
vector<int> right(n,n);
vector<int> height(n,0);
for(int i=0;i<m;i++){//行遍历
//cur_left,cur_right分别记录当前行到当前位置的连续1序列的开始位置和结束位置
int cur_left=0,cur_right=n;
for(int j=0;j<n;j++)//height更新
height[j]=(matrix[i][j]=='1')?height[j]+1:0;
for(int j=0;j<n;j++){
left[j]=(matrix[i][j]=='1')?max(left[j],cur_left):0;
cur_left=matrix[i][j]=='1'?cur_left:j+1;
}
for(int j=n-1;j>=0;j--){
right[j]=matrix[i][j]=='1'?min(right[j],cur_right):n;
cur_right=matrix[i][j]=='1'?cur_right:j;
}
for(int j=0;j<n;j++)
res=max(res,(right[j]-left[j])*height[j]);
}
return res;
}
};