84. 柱状图中最大的矩形
85. 最大矩形
221. 最大正方形
# 84. 柱状图中最大的矩形
class LargestRectangleArea:
"""
时间复杂度:O(N)
空间复杂度:O(N)
84. 柱状图中最大的矩形
https://leetcode.cn/problems/largest-rectangle-in-histogram/description/
"""
def solution(self, heights: List[int]) -> int:
n = len(heights)
if n == 0:
return 0
# left[i]和right[i] 分别表示 第i个元素的左右两侧的最近的高度小于heights[i]的柱子编号
left, right = [0] * n, [n] * n
# 单调递增栈
mono_stack = []
for i in range(n):
while mono_stack and heights[mono_stack[-1]] >= heights[i]:
right[mono_stack[-1]] = i
mono_stack.pop()
left[i] = mono_stack[-1] if mono_stack else -1
mono_stack.append(i)
ans = max((right[i]-left[i]-1) * heights[i] for i in range(n))
return ans
# 85. 最大矩形
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
if len(matrix) == 0:
return 0
max_area = 0
heights = [0 for _ in range(len(matrix[0]))]
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j] == '0':
heights[j] = 0
else:
heights[j] += 1
max_area = max(max_area, self.largestRectangleArea(heights))
return max_area
def largestRectangleArea(self, heights: List[int]) -> int:
n = len(heights)
if n == 0:
return 0
# left[i]和right[i] 分别表示 第i个元素的左右两侧的最近的高度小于heights[i]的柱子编号
left, right = [0] * n, [n] * n
# 单调递增栈
mono_stack = []
for i in range(n):
while mono_stack and heights[mono_stack[-1]] >= heights[i]:
right[mono_stack[-1]] = i
mono_stack.pop()
left[i] = mono_stack[-1] if mono_stack else -1
mono_stack.append(i)
ans = max((right[i]-left[i]-1) * heights[i] for i in range(n))
return ans
# 221. 最大正方形
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
# 动态规划
m, n = len(matrix), len(matrix[0])
# 定义:以 matrix[i][j] 为右下角元素的全为 1 正方形矩阵的最大边长为 dp[i][j]。
dp = [[0 for _ in range(n)] for _ in range(m)]
# base case,第一行和第一列的正方形边长
for i in range(m):
dp[i][0] = int(matrix[i][0])
for j in range(n):
dp[0][j] = int(matrix[0][j])
# 进行状态转移
for i in range(1, m):
for j in range(1, n):
if matrix[i][j] == '0':
# 值为 0 不可能是正方形的右下角
continue
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
max_len = 0
for i in range(m):
for j in range(n):
max_len = max(max_len, dp[i][j])
return max_len * max_len