原题
动态规划中等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.length
  • n == matrix[i].length
  • 1 <= m, n <= 300
  • matrix[i][j]'0''1'

查看原题

解题主线

  1. dp[row][column] 表示以当前位置为右下角的全 1 正方形最大边长。
  2. 当前位置为 1 时,边长由左、上、左上三个相邻状态的最小值加一决定。
  3. 第一行或第一列的 1 只能形成边长为 1 的正方形。

解法 1:右下角边长动态规划

按行扫描矩阵,以左、上、左上三个已知状态决定当前正方形边长,并维护全局最大边长。

  • 时间复杂度: O(mn)

  • 空间复杂度: O(mn)

JAVA
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