classSolution { public: intmaximalRectangle(vector<string>& matrix){ int m = matrix.size(); if (m == 0) { return0; } int n = matrix[0].size(); vector<vector<int>> left(m, vector<int>(n, 0));
for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (matrix[i][j] == '1') { left[i][j] = (j == 0 ? 0: left[i][j - 1]) + 1; } } }
int ret = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (matrix[i][j] == '0') { continue; } int width = left[i][j]; int area = width; for (int k = i - 1; k >= 0; k--) { width = min(width, left[k][j]); area = max(area, (i - k + 1) * width); } ret = max(ret, area); } } return ret; } };
var maximalRectangle = function(matrix) { const m = matrix.length; if (m === 0) { return0; } const n = matrix[0].length; const left = newArray(m).fill(0).map(() =>newArray(n).fill(0));
for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (matrix[i][j] === '1') { left[i][j] = (j === 0 ? 0 : left[i][j - 1]) + 1; } } }
let ret = 0; for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (matrix[i][j] === '0') { continue; } let width = left[i][j]; let area = width; for (let k = i - 1; k >= 0; k--) { width = Math.min(width, left[k][j]); area = Math.max(area, (i - k + 1) * width); } ret = Math.max(ret, area); } } return ret; };
funcmaximalRectangle(matrix []string) (ans int) { iflen(matrix) == 0 { return } m, n := len(matrix), len(matrix[0]) left := make([][]int, m) for i, row := range matrix { left[i] = make([]int, n) for j, v := range row { if v == '0' { continue } if j == 0 { left[i][j] = 1 } else { left[i][j] = left[i][j-1] + 1 } } } for i, row := range matrix { for j, v := range row { if v == '0' { continue } width := left[i][j] area := width for k := i - 1; k >= 0; k-- { width = min(width, left[k][j]) area = max(area, (i-k+1)*width) } ans = max(ans, area) } } return }
funcmin(a, b int)int { if a < b { return a } return b }
funcmax(a, b int)int { if a > b { return a } return b }
intmaximalRectangle(char** matrix, int matrixSize) { int m = matrixSize; if (m == 0) { return0; } int n = strlen(matrix[0]); int left[m][n]; memset(left, 0, sizeof(left)); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (matrix[i][j] == '1') { left[i][j] = (j == 0 ? 0 : left[i][j - 1]) + 1; } } }
int ret = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (matrix[i][j] == '0') { continue; } int width = left[i][j]; int area = width; for (int k = i - 1; k >= 0; k--) { width = fmin(width, left[k][j]); area = fmax(area, (i - k + 1) * width); } ret = fmax(ret, area); } } return ret; }
复杂度分析
时间复杂度:O(m^2n),其中 m 和 n 分别是矩阵的行数和列数。计算 left 矩阵需要 O(mn) 的时间。随后对于矩阵的每个点,需要 O(m) 的时间枚举高度。故总的时间复杂度为 O(mn) + O(mn) \cdot O(m) = O(m^2n)。
空间复杂度:O(mn),其中 m 和 n 分别是矩阵的行数和列数。我们分配了一个与给定矩阵等大的数组,用于存储每个元素的左边连续 1 的数量。
classSolution { public: intmaximalRectangle(vector<string>& matrix){ int m = matrix.size(); if (m == 0) { return0; } int n = matrix[0].size(); vector<vector<int>> left(m, vector<int>(n, 0));
for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (matrix[i][j] == '1') { left[i][j] = (j == 0 ? 0: left[i][j - 1]) + 1; } } }
int ret = 0; for (int j = 0; j < n; j++) { // 对于每一列,使用基于柱状图的方法 vector<int> up(m, 0), down(m, 0);
stack<int> stk; for (int i = 0; i < m; i++) { while (!stk.empty() && left[stk.top()][j] >= left[i][j]) { stk.pop(); } up[i] = stk.empty() ? -1 : stk.top(); stk.push(i); } stk = stack<int>(); for (int i = m - 1; i >= 0; i--) { while (!stk.empty() && left[stk.top()][j] >= left[i][j]) { stk.pop(); } down[i] = stk.empty() ? m : stk.top(); stk.push(i); }
for (int i = 0; i < m; i++) { int height = down[i] - up[i] - 1; int area = height * left[i][j]; ret = max(ret, area); } } return ret; } };
var maximalRectangle = function(matrix) { const m = matrix.length; if (m === 0) { return0; } const n = matrix[0].length; const left = newArray(m).fill(0).map(() =>newArray(n).fill(0));
for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (matrix[i][j] === '1') { left[i][j] = (j === 0 ? 0 : left[i][j - 1]) + 1; } } }
let ret = 0; for (let j = 0; j < n; j++) { // 对于每一列,使用基于柱状图的方法 const up = newArray(m).fill(0); const down = newArray(m).fill(0);
let stack = newArray(); for (let i = 0; i < m; i++) { while (stack.length && left[stack[stack.length - 1]][j] >= left[i][j]) { stack.pop(); } up[i] = stack.length === 0 ? -1 : stack[stack.length - 1]; stack.push(i); } stack = []; for (let i = m - 1; i >= 0; i--) { while (stack.length && left[stack[stack.length - 1]][j] >= left[i][j]) { stack.pop(); } down[i] = stack.length === 0 ? m : stack[stack.length - 1]; stack.push(i); }
for (let i = 0; i < m; i++) { const height = down[i] - up[i] - 1; const area = height * left[i][j]; ret = Math.max(ret, area); } } return ret; };