📅  最后修改于: 2023-12-03 14:55:49.828000             🧑  作者: Mango
给定一个由 0 和 1 组成的矩阵 matrix,找出一个最大的只包含 0 的正方形子矩阵,并返回其中元素数量。
我们可以暴力枚举每个起点,然后向右、向下扩展,检查是否存在只包含 0 的正方形子矩阵。
时间复杂度:O(n^4)
def maximalSquare(matrix) -> int:
row = len(matrix) # 行数
col = len(matrix[0]) # 列数
max_len = 0 # 记录最大正方形的边长
# 枚举起点
for i in range(row):
for j in range(col):
if matrix[i][j] == '1': # 跳过不是 0 的位置
continue
# 扩展正方形的右边和下边
length = 1
flag = True # 标记是否存在包含 1 的位置
while i + length < row and j + length < col and flag:
for k in range(i, i + length + 1):
if matrix[k][j + length] == '1':
flag = False
break
for k in range(j, j + length + 1):
if matrix[i + length][k] == '1':
flag = False
break
if flag: # 可以扩展正方形
length += 1
max_len = max(max_len, length) # 更新最大边长
return max_len ** 2
我们可以用一个 dp 数组来记录包含 i,j 位置的正方形的最大边长。
状态转移方程:
时间复杂度:O(n^2)
def maximalSquare(matrix) -> int:
row = len(matrix)
col = len(matrix[0])
dp = [[0] * (col + 1) for _ in range(row + 1)] # dp 表格
max_len = 0 # 记录最大正方形的边长
for i in range(1, row + 1):
for j in range(1, col + 1):
if matrix[i - 1][j - 1] == '1': # 跳过不是 0 的位置
continue
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1 # 计算 dp 值
max_len = max(max_len, dp[i][j]) # 更新最大边长
return max_len ** 2
本题可以用暴力枚举和动态规划两种方法解决。暴力枚举的时间复杂度较高,但思路简单易懂,而动态规划的时间复杂度较低,但需要理解状态转移方程。