题目地址
在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。
示例 1:
输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:4
示例 2:
输入:matrix = [[“0”,“1”],[“1”,“0”]]
输出:1
示例 3:
输入:matrix = [[“0”]]
输出:0
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j] 为 ‘0’ 或 ‘1’
解法:动态规划
dp(i,j):表示以(i,j)为右下角,且只包含1的正方形的边长最大值。
如果我们能计算出所dp(i,j)的值,那么其中的最大值即为矩阵中只包含1的正方形的边长最大值,其平方即为最大正方形的面积。
那么如何计算dp中的每个元素值呢?对于每个位置(i,j),检查在矩阵中该位置的值:
此外,还需要考虑边界条件。如果i和j中至少有一个为0,则以位置(i,j)为右下角的最大正方形的边长只能是1,因此dp(i,j)=1。
举例:
原始矩阵如下:
0 1 1 1 0
1 1 1 1 0
0 1 1 1 1
0 1 1 1 1
0 0 1 1 1
对应的dp值如下:
0 1 1 1 0
1 1 2 2 0
0 1 2 3 1
0 1 2 3 2
0 0 1 2 3
计算dp值的过程:
步骤:
1.特判,若matrix为空,返回0
2.初试化matrix的行rows,列columns,初始化dp=[[0,⋯,0],⋯,[0,⋯,0]],维度为(rows+1)∗(columns+1),这样便于处理。初始化最大边长maxSide=0。
3.遍历dp数组,遍历行rows,遍历区间[0,rows):
遍历列j,遍历区间[0,columns):
若matrix[i−1][j−1]==“1”,此时可能存在正方形:
dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])+1
并更新最大边长maxSide=max(maxSide,dp[i][j])
4.返回面积maxSide∗maxSide
代码实现:
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
if len(matrix) == 0 or len(matrix[0]) == 0:
return 0
maxSide = 0
rows, columns = len(matrix), len(matrix[0])
dp = [[0] * columns for _ in range(rows)]
for i in range(rows):
for j in range(columns):
if matrix[i][j] == '1':
if i == 0 or j == 0:
dp[i][j] = 1
else:
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
maxSide = max(maxSide, dp[i][j])
maxSquare = maxSide * maxSide
return maxSquare