Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
» Solve this problem
题目要求的是由1组成的最大的矩形。
附上一个图能更好地说明题意:
1 | 0 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 0 |
1 | 0 | 1 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 1 | 1 |
全部由1组成的矩形有:
面积为1,23个(可能数错了,欢迎大家指正);
面积为2,29个;
面积为3,15个;
面积为4,15个;
面积为5,3个;
面积为6,4个;
面积为8,1个( (3,2) -> (4, 5) )
最大的矩形面积为8。
其实这题稍加转换后就是Largest Rectangle in Histogram。
先看第一行,1 0 0 0 1 1,Largest Rectangle in Histogram为2。
再看第一行+第二行, 1 0 0 0 1 1
1 1 1 0 1 1,转化为Histogram,就是2 1 1 0 2 2,Largest Rectangle in Histogram为4。
所以,我的思路就是遍历所有行,当遍历第i行时,将1~i转化为Histogram,求出Largest Rectangle。
class Solution {
public:
int maximalRectangle(vector<vector<char> > &matrix) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int m = matrix.size();
if (m == 0) {
return 0;
}
int n = matrix[0].size();
if (n == 0) {
return 0;
}
int max = 0;
int height[n], l[n], r[n];
memset(height, 0, sizeof(int) * n);
for (int i = 0; i < m; i++) {
memset(l, 0, sizeof(int) * n);
memset(r, 0, sizeof(int) * n);
for (int j = 0; j < n; j++) {
if (i == 0) {
height[j] = matrix[i][j] == '0' ? 0 : 1;
}
else {
height[j] = matrix[i][j] == '0' ? 0 : height[j] + 1;
}
}
for (int j = 0; j < n; j++) {
if (j == 0 || height[j - 1] < height[j]) {
l[j] = j;
}
else {
int idx = l[j - 1];
while (idx > 0 && height[j] <= height[idx - 1]) {
idx = l[idx - 1];
}
l[j] = idx;
}
}
for (int j = n - 1; j >= 0; j--) {
if (j == n - 1 || height[j + 1] < height[j]) {
r[j] = j;
}
else {
int idx = r[j + 1];
while (idx < n - 1 && height[j] <= height[idx + 1]) {
idx = r[idx + 1];
}
r[j] = idx;
}
}
for (int j = 0; j < n; j++) {
if ((r[j] - l[j] + 1) * height[j] > max) {
max = (r[j] - l[j] + 1) * height[j];
}
}
}
return max;
}
};