问题描述
在一个由 '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 解释:右下角存在一个 2x2 的全为 '1' 的正方形,面积为 4。
示例 2: 输入:matrix = [["0"]] 输出:0
示例 3: 输入:matrix = [["1"]] 输出:1
解题思路
核心观察:要判断以 (i, j) 为右下角的最大正方形边长,需要知道其左、上、左上三个方向能构成的最大正方形边长。这天然适合使用动态规划(DP)。
方法一:动态规划(推荐)
状态定义:设 dp[i][j] 表示以 (i, j) 为右下角的最大正方形的边长。
状态转移方程:
- 如果 matrix[i][j] == '0',则 dp[i][j] = 0
- 如果 matrix[i][j] == '1',则 dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
边界处理:第 0 行和第 0 列可直接初始化为 matrix[i][j] - '0'。
答案:遍历过程中记录 maxSide = max(maxSide, dp[i][j]),最终返回 maxSide * maxSide。
方法二:暴力枚举(不推荐)
枚举每个位置作为正方形左上角,尝试扩展边长直到越界或遇到 '0'。时间复杂度高,会超时。
方法三:优化空间的 DP
由于 dp[i][j] 只依赖于当前行和上一行,可用两个一维数组压缩空间。
代码实现
// Java - 动态规划(标准二维 DP)
class Solution {
public int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
int m = matrix.length, n = matrix[0].length;
int[][] dp = new int[m][n];
int maxSide = 0;
for ( ; i < m; i++) {
( ; j < n; j++) {
(matrix[i][j] == ) {
(i == || j == ) {
dp[i][j] = ;
} {
dp[i][j] = Math.min(Math.min(dp[i - ][j], dp[i][j - ]), dp[i - ][j - ]) + ;
}
maxSide = Math.max(maxSide, dp[i][j]);
}
}
}
maxSide * maxSide;
}
}


