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; } }