剑指 Offer II 040. 矩阵中最大的矩形
给定一个由 0
和 1
组成的矩阵 matrix
,找出只包含 1
的最大矩形,并返回其面积。
注意:此题 matrix
输入格式为一维 01
字符串数组。
示例 1:
输入:matrix = ["10100","10111","11111","10010"] 输出:6 解释:最大矩形如上图所示。
示例 2:
输入:matrix = [] 输出:0
示例 3:
输入:matrix = ["0"] 输出:0
示例 4:
输入:matrix = ["1"] 输出:1
示例 5:
输入:matrix = ["00"] 输出:0
提示:
rows == matrix.length
cols == matrix[0].length
0 <= row, cols <= 200
matrix[i][j]
为 '0'
或 '1'
注意:本题与主站 85 题相同(输入参数格式不同): https://leetcode.cn/problems/maximal-rectangle/
原站题解
python3 解法, 执行用时: 64 ms, 内存消耗: 15.3 MB, 提交时间: 2023-04-22 12:23:08
class Solution: def maximalRectangle(self, matrix: List[str]) -> int: def maxheight(height: List, res: int): stack = [-1] for i, num in enumerate(height): while stack[-1] != -1 and height[stack[-1]] > num: pre_i = stack.pop() res = max(res, (i - stack[-1] - 1) * height[pre_i]) stack.append(i) while stack[-1] != -1: pre_i = stack.pop() res = max(res, (len(height) - stack[-1] - 1) * height[pre_i]) return res if not matrix: return 0 heights, ans = [0] * len(matrix[0]), 0 for i in range(len(matrix)): for j in range(len(matrix[0])): if matrix[i][j] == '0': heights[j] = 0 elif i > 0 and matrix[i - 1][j] == '0': heights[j] = int(matrix[i][j]) else: heights[j] += 1 ans = maxheight(heights, ans) return ans
java 解法, 执行用时: 13 ms, 内存消耗: 41.4 MB, 提交时间: 2023-04-22 12:22:52
class Solution { public int maximalRectangle(String[] matrix) { int m = matrix.length; if (m == 0) { return 0; } int n = matrix[0].length(); int[][] left = new int[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (matrix[i].charAt(j) == '1') { left[i][j] = (j == 0 ? 0 : left[i][j - 1]) + 1; } } } int ret = 0; for (int j = 0; j < n; j++) { // 对于每一列,使用基于柱状图的方法 int[] up = new int[m]; int[] down = new int[m]; Deque<Integer> stack = new ArrayDeque<Integer>(); for (int i = 0; i < m; i++) { while (!stack.isEmpty() && left[stack.peek()][j] >= left[i][j]) { stack.pop(); } up[i] = stack.isEmpty() ? -1 : stack.peek(); stack.push(i); } stack.clear(); for (int i = m - 1; i >= 0; i--) { while (!stack.isEmpty() && left[stack.peek()][j] >= left[i][j]) { stack.pop(); } down[i] = stack.isEmpty() ? m : stack.peek(); stack.push(i); } for (int i = 0; i < m; i++) { int height = down[i] - up[i] - 1; int area = height * left[i][j]; ret = Math.max(ret, area); } } return ret; } }
javascript 解法, 执行用时: 84 ms, 内存消耗: 45.8 MB, 提交时间: 2023-04-22 12:22:23
/** * @param {string[]} matrix * @return {number} */ var maximalRectangle = function(matrix) { const m = matrix.length; if (m === 0) { return 0; } const n = matrix[0].length; const left = new Array(m).fill(0).map(() => new Array(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 = new Array(m).fill(0); const down = new Array(m).fill(0); let stack = new Array(); 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; };
golang 解法, 执行用时: 0 ms, 内存消耗: 5.1 MB, 提交时间: 2023-04-22 12:22:08
func maximalRectangle(matrix []string) (ans int) { if len(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 j := 0; j < n; j++ { // 对于每一列,使用基于柱状图的方法 up := make([]int, m) down := make([]int, m) stk := []int{} for i, l := range left { for len(stk) > 0 && left[stk[len(stk)-1]][j] >= l[j] { stk = stk[:len(stk)-1] } up[i] = -1 if len(stk) > 0 { up[i] = stk[len(stk)-1] } stk = append(stk, i) } stk = nil for i := m - 1; i >= 0; i-- { for len(stk) > 0 && left[stk[len(stk)-1]][j] >= left[i][j] { stk = stk[:len(stk)-1] } down[i] = m if len(stk) > 0 { down[i] = stk[len(stk)-1] } stk = append(stk, i) } for i, l := range left { height := down[i] - up[i] - 1 area := height * l[j] ans = max(ans, area) } } return } func max(a, b int) int { if a > b { return a } return b }
golang 解法, 执行用时: 12 ms, 内存消耗: 3.2 MB, 提交时间: 2023-04-22 12:21:57
func maximalRectangle(matrix []string) (ans int) { if len(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 } func min(a, b int) int { if a < b { return a } return b } func max(a, b int) int { if a > b { return a } return b }
javascript 解法, 执行用时: 140 ms, 内存消耗: 42.9 MB, 提交时间: 2023-04-22 12:21:40
/** * @param {string[]} matrix * @return {number} */ var maximalRectangle = function(matrix) { const m = matrix.length; if (m === 0) { return 0; } const n = matrix[0].length; const left = new Array(m).fill(0).map(() => new Array(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; };
java 解法, 执行用时: 14 ms, 内存消耗: 41.1 MB, 提交时间: 2023-04-22 12:21:27
class Solution { public int maximalRectangle(String[] matrix) { int m = matrix.length; if (m == 0) { return 0; } int n = matrix[0].length(); int[][] left = new int[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (matrix[i].charAt(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].charAt(j) == '0') { continue; } int width = left[i][j]; int area = width; for (int 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; } }