📅  最后修改于: 2023-12-03 15:34:33.721000             🧑  作者: Mango
给定一个由数字 0 和 1 组成的矩阵,找出其中最大的全 1 子矩阵。
示例:
输入:
[ ["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"] ]
输出: 6
此题可以使用动态规划的思想来解决,定义一个一维数组 heights
来存储每一行的以该行为底的连续 1 的个数。
例如:
[
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]
]
可以得到一个 heights
数组为:
[1, 0, 1, 0, 0]
[2, 0, 2, 1, 1]
[3, 1, 3, 2, 2]
[4, 0, 0, 3, 0]
每一行都看成一个直方图,然后根据每一列迭代计算,可以得到一个函数 maxArea(heights)
来计算以该列为底的最大矩形面积。
使用求解最大面积的方法遍历每一列,得到最大子矩阵的面积即可。
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
if not matrix:
return 0
m, n = len(matrix), len(matrix[0])
heights = [0] * n
res = 0
for i in range(m):
for j in range(n):
heights[j] = heights[j] + 1 if matrix[i][j] == '1' else 0
res = max(res, self.maxArea(heights))
return res
def maxArea(self, heights: List[int]) -> int:
if not heights:
return 0
n = len(heights)
left, right = [0] * n, [0] * n
left[0], right[-1] = -1, n
for i in range(1, n):
tmp = i - 1
while tmp >= 0 and heights[tmp] >= heights[i]:
tmp = left[tmp]
left[i] = tmp
for i in range(n - 2, -1, -1):
tmp = i + 1
while tmp < n and heights[tmp] >= heights[i]:
tmp = right[tmp]
right[i] = tmp
res = 0
for i in range(n):
res = max(res, (right[i] - left[i] - 1) * heights[i])
return res
时间复杂度:O(MN)
空间复杂度:O(N)
其中 M 和 N 分别为输入矩阵的行和列数。