动态规划中等1 种解法
#221最大正方形
在只包含 0 和 1 的字符矩阵中,返回全为 1 的最大正方形面积。
#矩阵#动态规划
原题
在一个由 '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.lengthn == matrix[i].length1 <= m, n <= 300matrix[i][j]为'0'或'1'
解题主线
- dp[row][column] 表示以当前位置为右下角的全 1 正方形最大边长。
- 当前位置为 1 时,边长由左、上、左上三个相邻状态的最小值加一决定。
- 第一行或第一列的 1 只能形成边长为 1 的正方形。
解法 1:右下角边长动态规划
按行扫描矩阵,以左、上、左上三个已知状态决定当前正方形边长,并维护全局最大边长。
-
时间复杂度: O(mn)
-
空间复杂度: O(mn)
final class Solution {
public int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int rows = matrix.length;
int columns = matrix[0].length;
int[][] dp = new int[rows][columns];
int maximumSide = 0;
for (int row = 0; row < rows; row++) {
for (int column = 0; column < columns; column++) {
// 只有字符 1 才可能作为全 1 正方形的右下角。
if (matrix[row][column] != '1') continue;
if (row == 0 || column == 0) {
// 第一行或第一列最多形成边长为 1 的正方形。
dp[row][column] = 1;
} else {
// 边长受左、上、左上三个相邻正方形中的最短边限制。
dp[row][column] = 1 + Math.min(
dp[row - 1][column - 1],
Math.min(dp[row - 1][column], dp[row][column - 1])
);
}
maximumSide = Math.max(maximumSide, dp[row][column]);
}
}
// DP 记录的是边长,题目要求返回面积。
return maximumSide * maximumSide;
}
}边界与易错点
- 最终要求面积,记录的最大边长必须平方后返回。
- 只有 matrix[row][column] == '1' 时才能进行状态转移。
- 访问 matrix[0] 前先处理 null 或空矩阵。
整理来源
由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。
leetcode/src/main/java/medium/Q221_maximalSquare_dp.java