Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
// LeetCode, Maximal Rectangle
// 时间复杂度O(n^2),空间复杂度O(n)
class Solution {
public:
int maximalRectangle(vector > &matrix) {
if (matrix.empty()) return 0;
const int m = matrix.size();
const int n = matrix[0].size();
vector H(n, 0);
vector L(n, 0);
vector R(n, n);
int ret = 0;
// 每一个点只算 它 上面的高度 H 记录的是前面累计的高度,没有下面行H的累计,下面的行由下一个点去算
for (int i = 0; i < m; ++i) { // i循环,这一行 H[j] ; L[j] ; R[j] 的状态会影响 影响推进 下一行的 H[j] ; L[j] ; R[j] 状态
int left = 0;//上次出现0之后的位置,即left就是1开始的位置
int right = n;//right是最后一个0的位置不是1开始的位置,是1开始位置的前一个(从右往左)
// calculate L(i, j) from left to right
for (int j = 0; j < n; ++j) {
if (matrix[i][j] == '1') {
++H[j];
// 从 max( 【上一行】的L,【前一列】的left ) 得出这个点的L
/* 如 1100
1100
0100 点(2,1)的状态 起始left=1( 前一个点(2,0)为0导致的);L[j]=0;h[j]=2;然后++h[j]等于3;L[j]=max(left=1,L[j]=0)==1
*/
L[j] = max(L[j], left);//matrix[i][j] == '1'时,left不变,一直保持上次出现0之后的位置,即left就是1开始的位置
} else {
left = j+1; // j列循环,前一列left影响下了一列
H[j] = 0; L[j] = 0; R[j] = n;
}
}
// calculate R(i, j) from right to left
for (int j = n-1; j >= 0; --j) {
if (matrix[i][j] == '1') {
R[j] = min(R[j], right);//right是最后一个0的位置不是1开始的位置,是1开始位置的前一个(从右往左)
ret = max(ret, H[j]*(R[j]-L[j])); // 所以这里没有 R[j]-L[j]+1,因为right多算了一个1
} else {
right = j;
}
}
}
return ret;
}
};