leetcode 221. Maximal Square

博客围绕在由0和1构成的二维数组中找最大正方形面积展开。思路是利用正方形长和宽相等,较短边决定边长的特性,用dp数组记录从(0, 0)到每个位置能构成的正方形边长,通过左、上、左斜上方最短边长确定当前位置边长,计算中保存最大边长,最后返回边长平方作为面积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a 2D binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area.

Example:
在这里插入图片描述

给出一个由0,1构成的二维数组,让找出里面最大的正方形的面积

思路:
因为是正方形,长和宽是一样的,较短的一方决定了正方形的边长

假如给一个input
0   1
1   1

依次看(0,0), (0,1), (1,0), (1,1)位置,从(0,0)出发看到这些位置的正方形的边长
(0, 0):input[0][0]=0,不是1,所以不能作为正方形,边长是0
(0, 1):input[0][1] = 1, 它左边是0,当然上面和左斜上方可以想成是0,它本身可以构成边长是1的正方形,所以边长是1
(1, 0):input[1][0] = 1, 它上面是0,当然左边和左斜上方可以想成是0,它本身可以构成边长是1的正方形,所以边长是1
(1, 1):input[1][1] = 1, 虽然说它的上面和左边是1,但是左斜上方是0,限制了它不能构成正方形,左,上,左斜上方最短的边长决定了现在(1,1)位置的正方形边长,(1,1)本身的边长是1,再加上左,上,左斜上方最短的边长,即min(左,上,左斜上方边长)+1 = 1

再比如:
0   1     1  1
1   1     1  1

1   1     1  1
1   1     1  1

一次看2✖️2的正方形,所以加了一些空格分开这些值,
可以看到这4个2✖️2的正方形的边长是:
1    2
2    2
因为左,上,左斜上方最短的边长限制了整体(0,0)到右下角的正方形边长,
所以整体正方形的边长是min(左,上,左斜上方边长)+右下角小正方形边长2 = 3

推广:
因为是正方形,长和宽是一样的,较短的一方决定了正方形的边长

用一个dp数组记录从(0, 0)出发到达每个(i,j)能构成的正方形的边长
对每个input[i][j]=1,它的左,上,左斜上方的最短边长决定了当前dp[i][j]

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

如果dp[i][j] = 0, 显然是不能构成正方形的,直接=0

因为最大边长不确定出现在哪里,所以在dp计算过程中,保存下最大的边长。

最后结果因为是求面积,所以返回边长*边长

    public int maximalSquare(char[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return 0;
        }
        
        int[][] dp = new int[matrix.length][matrix[0].length];
        int result = 0;
        
        dp[0][0] = matrix[0][0] - '0';
        result = dp[0][0];
        
        //left border..
        for (int i = 1; i < matrix.length; i++) {
            dp[i][0] = matrix[i][0] - '0';
            result = Math.max(result, dp[i][0]);
        }
        
        //top border..
        for (int j = 1; j < matrix[0].length; j++) {
            dp[0][j] = matrix[0][j] - '0';
            result = Math.max(result, dp[0][j]);
        }
        
        for (int i = 1; i < matrix.length; i++) {
            for (int j = 1; j < matrix[0].length; j++) {
                if (matrix[i][j] == '0') {
                    dp[i][j] = 0;
                } else {
                    dp[i][j] = Math.min(dp[i - 1][j - 1], 
                                        Math.min(dp[i - 1][j], dp[i][j - 1])) + 1;
                }
                
                result = Math.max(result, dp[i][j]);
            }
        }
        
        return (result*result);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值