1. 问题描述:
给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例 1:
输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示
示例 2:
输入:matrix = []
输出:0
示例 3:
输入:matrix = [["0"]]
输出:0
示例 4:
输入:matrix = [["1"]]
输出:1
示例 5:
输入:matrix = [["0","0"]]
输出:0
提示:
rows == matrix.length
cols == matrix[0].length
1 <= row, cols <= 200
matrix[i][j] 为 '0' 或 '1'
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximal-rectangle/
2. 思路分析:
官方提供了一个暴力优化做法是使用一个二维数组 left 预处理第 i 行以 j 结尾往前最多连续 1 的数目,最后枚举矩阵中的每一个位置 matrix[i][j],如果当前位置为 '1',那么从当前这一行往上一直到第 0 行更新以当前这一列往左的矩阵的最大面积。
3. 代码如下:
python:
from typing import List
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
n, m = len(matrix), len(matrix[0])
left = [[0] * m for i in range(n)]
# 计算以当前位置(i, j)连续的1的数目
for i in range(n):
for j in range(m):
if matrix[i][j] == "1":
left[i][j] = (0 if j == 0 else left[i][j - 1]) + 1
res = 0
for i in range(n):
for j in range(m):
if matrix[i][j] == "0": continue
width = left[i][j]
area = width
for k in range(i - 1, -1, -1):
width = min(width, left[k][j])
area = max(area, (i - k + 1) * width)
res = max(res, area)
return res
go:
package main
import "fmt"
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
}
func maximalRectangle(matrix [][]byte) int {
n := len(matrix)
m := len(matrix[0])
left := make([][]int, n)
for i := 0; i < n; i++ {
left[i] = make([]int, m)
}
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if matrix[i][j] == '1' {
if j == 0 {
left[i][j] = 1
} else {
left[i][j] = left[i][j-1] + 1
}
}
}
}
res := 0
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if matrix[i][j] == '1' {
width := left[i][j]
area := left[i][j]
for k := i - 1; k >= 0; k-- {
width = min(width, left[k][j])
area = max(area, width*(i-k+1))
}
res = max(res, area)
}
}
}
return res
}