Solution 1
这道题其实就是85. Maximal Rectangle 的二维变体,我本来打算从二维的方式考虑状态迭代,然后失败了,因为向四角探索的过程中还要额外考虑边缘的连通性(不存在0),时间复杂度会扩展到三次方(或许有更好的方式维护状态?),因此作罢。另外一个思路就是按行累加构成直方图,每一行的直方图都计算一次,二次方时间复杂度就能够得到结果。
空间上面其实可以优化一下,就是处理的过程中直接进行累加,这样只需要一个一维数组。
- 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 m m m和 n n n为输入数据的行数和列数,数据处理以及遍历和累加过程
- 空间复杂度: O ( m ) O(m) O(m),其中 m m m为输入数据的行数,处理后的数据占用
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
// 图处理和直方图归置
int row = matrix.size();
if (row == 0) {
return 0;
}
int col = matrix[0].size();
vector<int> heights(col, 0);
int ans = -1;
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
heights[j] = matrix[i][j] == '0' ? 0 : (1 + heights[j]);
}
ans = max(largestRectangleArea(heights), ans);
}
return ans;
}
private:
int largestRectangleArea(vector<int>& heights) {
int length = heights.size();
vector<int> boundLeft(length, -1), boundRight(length, length);
stack<int> monoLeft;
for (int i = 0; i < length; ++i) {
while (!monoLeft.empty() && heights[monoLeft.top()] >= heights[i]) {
boundRight[monoLeft.top()] = i;
monoLeft.pop();
}
boundLeft[i] = monoLeft.empty() ? -1 : monoLeft.top();
monoLeft.push(i);
}
int ans = -1;
for (int i = 0; i < length; ++i) {
ans = max(ans, (boundRight[i] - boundLeft[i] - 1) * heights[i]);
}
return ans;
}
};
Solution 2
Solution 1的Python实现
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
row = len(matrix)
if row == 0: return 0
col = len(matrix[0])
heights = [0] * col
ans = -1
for i in range(row):
for j in range(col):
heights[j] = 0 if matrix[i][j] == '0' else 1 + heights[j]
ans = max(self.largestRectangleArea(heights), ans)
return ans
def largestRectangleArea(self, heights: List[int]) -> int:
length = len(heights)
boundLeft, boundRight = [0] * length, [length] * length
monoLeft = list()
for i in range(length):
while monoLeft and heights[monoLeft[-1]] >= heights[i]:
boundRight[monoLeft[-1]] = i
monoLeft.pop()
boundLeft[i] = monoLeft[-1] if monoLeft else -1
monoLeft.append(i)
ans = -1
for i in range(length):
ans = max((boundRight[i] - boundLeft[i] - 1) * heights[i], ans)
return ans