相似题目:
【LeetCode】84. 柱状图中最大的矩形(单调栈).
1. 题目描述:
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例:
输入:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
输出: 6
2. 解题思路
2.1 法一、单调栈
具体可参考【LeetCode】84. 柱状图中最大的矩形(单调栈) 这一题目,代码都相似
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
if not matrix:
return 0
# 单调栈的应用 2
def getLargestRectLayer(heights):
ret = 0
stack = []
heights = [0] + heights + [0]
for i in range(len(heights)):
while stack and heights[stack[-1]] > heights[i]:
tmp = stack.pop()
ret = max(ret, (i - stack[-1] - 1) * heights[tmp])
stack.append(i)
return ret
def getHeights(array, heights):
for i in range(len(heights)):
if array[i] == "1":
heights[i] += 1
else:
heights[i] = 0
return heights
# 对于每一层 获取heights数组即可
ret = 0
m = len(matrix)
for i in range(m):
if i == 0:
heights = list(map(int, matrix[0]))
else:
heights = getHeights(matrix[i], heights)
retLayer = getLargestRectLayer(heights)
ret = max(ret, retLayer)
return ret
2.2 法二、动态规划
面试的时候用的是动态规划,当时面试官就问说能不能用栈来解题
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
maxarea = 0
dp = [[0] * len(matrix[0]) for _ in range(len(matrix))]
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j] == '0': continue
# compute the maximum width and update dp with it
width = dp[i][j] = dp[i][j-1] + 1 if j else 1
# compute the maximum area rectangle with a lower right corner at [i, j]
for k in range(i, -1, -1):
width = min(width, dp[k][j])
maxarea = max(maxarea, width * (i-k+1))
return maxarea
复杂度分析
-
时间复杂度 : O ( N 2 M ) O(N^2M) O(N2M) 。由于需要遍历同一列中的值,计算每个点对应最大面积需要 O ( N ) O(N) O(N)。对全部 N ∗ M N * M N∗M个点都要计算,因此总共 O ( N ) ∗ O ( N M ) = O ( N 2 M ) O(N) * O(NM) = O(N^2M) O(N)∗O(NM)=O(N2M).
-
空间复杂度 : O ( N M ) O(NM) O(NM)。我们分配了一个等大的数组,用于存储每个点的最大宽度。