LeetCode 221 & 1277

221: https://leetcode-cn.com/problems/maximal-square/

1277: https://leetcode-cn.com/problems/count-square-submatrices-with-all-ones/

今天在攻坚DP问题,刷到这两道十分相似的计算正方形个数/面积的题目,现在来总结一下。

1277题的思路我是看这位大哥的想法想出来的:https://leetcode-cn.com/problems/count-square-submatrices-with-all-ones/solution/tong-ji-quan-wei-1-de-zheng-fang-xing-zi-ju-zhen-f/

其思路 :通过他的分析我们也知道一个边长为3的正方形,肯定包括了边长为2的正方形,同时也包括边长为1的 ,我们就需要使用一个res变量来统计遇到不同边长的正方形个数。

每次把matrix[i][j] == 1 的方块作为这个“正方形”的右下角,然后去向左,上,左上这三个方向去找,取这三个位置的最小值来加上matrix[i][j],然后赋值给dp[i][j],表示以这个点为右下角的点的正方形的最大边长。

class Solution {
    public int countSquares(int[][] matrix) {
        int[][] dp = new int[matrix.length][matrix[0].length];
        int res = 0;
        for(int i = 0; i < matrix.length; i++){
            dp[i][0] = matrix[i][0];
            res += dp[i][0];
        }
        for(int i = 1; i < matrix[0].length; i++){
            dp[0][i] = matrix[0][i];
            res += dp[0][i];
        }
        for(int i = 1; i< matrix.length; i++){
            for(int j = 1; j < matrix[i].length; j++){
                if(matrix[i][j] == 1){
                    dp[i][j] = Math.min(dp[i-1][j], Math.min(dp[i][j-1], dp[i-1][j-1])) + 1;
                    res += dp[i][j];
                }
            }
        }
        return res;
    }
}

他的题析也提到了221题,我也顺便做了,其实一样的思路,221题我们在找到了整个矩阵中最长的边长后,返回max * max即可。

class Solution {
    public int maximalSquare(char[][] matrix) {
        if(matrix.length == 0 || matrix[0].length == 0){
            return 0;
        }
        int[][] dp = new int[matrix.length][matrix[0].length];
        int max = 0;
        for(int i = 0; i < matrix.length; i++){
            dp[i][0] = matrix[i][0] - '0';
            max = Math.max(dp[i][0],max);
        }
        for(int i = 1; i < matrix[0].length; i++){
            dp[0][i] = matrix[0][i] - '0';
            max = Math.max(dp[0][i],max);
        }
        for(int i = 1; i < matrix.length; i++){
            for(int j = 1; j < matrix[0].length; j++){
                if(matrix[i][j] == '1'){
                    dp[i][j] = Math.min(Math.min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1;
                    max = Math.max(dp[i][j],max);
                }
            }
        }
        return max * max;
    }
}
原文地址:https://www.cnblogs.com/ZJPaang/p/12844629.html