xqqlyx

221. 最大正方形

题目

描述

给定一个由 '0' 和 '1' 组成的2维矩阵,返回该矩阵中最大的由 '1' 组成的正方形的面积。输入的矩阵是字符形式而非数字形式。

链接http://https://www.nowcoder.com/practice/0058c4092cec44c2975e38223f10470e

思路

定义 DP 数组:设 dp[i][j] 表示以 (i,j) 为右下角的最大正方形的边长。
状态转移方程:若当前位置 matrix[i][j] == '1',则 dp[i][j] 由其上方、左方、左上方三个位置的 dp 值决定:

dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1

实际上是一个扩展判定填表的过程
定义右上角、左上角、左下角均可,就是需要编写代码的时候控制好循环变量填表计算。
如左上角最大正方形

dp[i][j] = min(dp[i][j+1], dp[i+1][j], dp[i+1][j+1]) + 1

完整代码

public class Solution {
    public int maximalSquare(char[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return 0;
        }
        int rows = matrix.length;
        int cols = matrix[0].length;
        int[][] dp = new int[rows][cols];
        int maxSide = 0; // 记录最大正方形的边长

        // 初始化第一行和第一列
        for (int i = 0; i < rows; i++) {
            if (matrix[i][0] == '1') {
                dp[i][0] = 1;
                maxSide = Math.max(maxSide, dp[i][0]);
            }
        }
        for (int j = 0; j < cols; j++) {
            if (matrix[0][j] == '1') {
                dp[0][j] = 1;
                maxSide = Math.max(maxSide, dp[0][j]);
            }
        }

        // 填充dp数组的其他位置
        for (int i = 1; i < rows; i++) {
            for (int j = 1; j < cols; j++) {
                if (matrix[i][j] == '1') {
                    // 取上方、左方、左上方的最小值,加1
                    dp[i][j] = Math.min(Math.min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1;
                    maxSide = Math.max(maxSide, dp[i][j]);
                } else {
                    dp[i][j] = 0;
                }
            }
        }
        return maxSide * maxSide; // 返回面积
    }
}

posted on 2025-09-28 15:59  烫烫烫烫热  阅读(4)  评论(0)    收藏  举报