# [221] 最大正方形
在一个由 '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
matrix[i][j] 为 '0' 或 '1'
动态规划一类的问题,求解大多不难,难的是想到重复的子问题结构。
例如本题,我们需要通过观察,找出一个由1组成的正方形是如何扩大的,其推导过程是怎样的。
我们可以发现,当 matrix[i][j] 为 1,且它的左边、上边、左上边都为正方形时,matrix[i][j] 才能够成为一个更大的正方形的右下角。而其能够组成的最大正方形为,左边、上边、左上边的正方形的最小值 + 1。
观察到这个规律,我们即可设 dp[i][j] 为以 (i, j) 为右下角时,所组成的最大正方形的边长,并最终求解。
function maximalSquare(matrix: string[][]): number {
const rowLen = matrix.length;
const colLen = matrix[0].length;
// 设 dp[i][j] 为以 (i, j) 为右下角时,所组成的最大正方形的边长
const dp: number[][] = Array(rowLen + 1)
.fill(0)
.map(x => Array(colLen + 1).fill(0));
let res = 0;
for (let i = 1; i <= rowLen; i++) {
for (let j = 1; j <= colLen; j++) {
// 当 matrix[i][j] 为 1,且它的左边、上边、左上边都为正方形时,matrix[i][j] 才能够成为一个更大的正方形的右下角
if (matrix[i - 1][j - 1] === '1') {
dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1;
res = Math.max(res, dp[i][j]);
}
}
}
return res> res;
}