给你一个 m * n 的矩阵,矩阵中的元素不是 0 就是 1,请你统计并返回其中完全由 1 组成的 正方形 子矩阵的个数。
示例 1:
输入:matrix =
[
[0,1,1,1],
[1,1,1,1],
[0,1,1,1]
]
输出:15
解释:
边长为 1 的正方形有 10 个。
边长为 2 的正方形有 4 个。
边长为 3 的正方形有 1 个。
正方形的总数 = 10 + 4 + 1 = 15.
示例 2:
输入:matrix =
[
[1,0,1],
[1,1,0],
[1,1,0]
]
输出:7
解释:
边长为 1 的正方形有 6 个。
边长为 2 的正方形有 1 个。
正方形的总数 = 6 + 1 = 7.
提示:
1 <= arr.length <= 300
1 <= arr[0].length <= 300
0 <= arr[i][j] <= 1
1.
/** * @param {number[][]} matrix * @return {number} */ var countSquares = function(matrix) { let temp = []; let width = 0; let length = 0; let min = (matrix.length>matrix[0].length?matrix[0].length:matrix.length)-1; while(width<=min){ length = 0; for(let i=0;i<matrix.length;i++){ for(let j=0;j<matrix[0].length;j++){ if(matrix[i][j]!=0){ let flag = true; for(let k=0;k<=width;k++){ for(let z=0;z<=width;z++){ if(i+k>=matrix.length||j+z>=matrix[0].length||matrix[i+k][j+z]==0){ flag = false; break; } } } if(flag == true){ length++; } } } } temp.push(length); width++; } return temp.reduce((pre,item)=>{return pre+item},0) };
实现:循环测试边长为n的正方形的个数,正方形的判断方式当其向右移动n位和向下移动n位的范围内的所有的元素都得是1才能是正方形。超时的主要问题是,之前计算的结果没有被利用
2.
class Solution { public int countSquares(int[][] matrix) { int m = matrix.length; int n = matrix[0].length; int len = Math.min(m, n); boolean[][][] dp = new boolean[m][n][len]; int count = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { dp[i][j][0] = (matrix[i][j] == 1); count += dp[i][j][0] ? 1 : 0; } } for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { for (int k = 1; k < len; k++) { dp[i][j][k] = (matrix[i][j] == 1 && dp[i - 1][j][k - 1] && dp[i][j - 1][k - 1] && dp[i - 1][j - 1] [k - 1]); if (dp[i][j][k]) { count++; } } } } return count; } }
/** * @param {number[][]} matrix * @return {number} */ var countSquares = function(matrix) { let temp = []; let count=0; let min_length = Math.min(matrix.length,matrix[0].length); //初始化三维数组 for(let i=0;i<matrix.length;i++){ let demo = new Array(matrix[0].length); for(let j=0;j<matrix[0].length;j++){ demo[j] = new Array(min_length); for(let k=0;k<min_length;k++){ demo[j][k] = 0; } } temp.push(demo) } //边长为1的正方形个数 for(let i=0;i<matrix.length;i++){ for(let j=0;j<matrix[0].length;j++){ temp[i][j][0] = (matrix[i][j] === 1?1:0); //循环判断当前的元素是否边长为1 if(temp[i][j][0]){ count++;//边长为1的个数 } } } //从2开始的编程 for(let i=1;i<matrix.length;i++){ for(let j=1;j<matrix[0].length;j++){ for(let k = 1;k<min_length;k++){ temp[i][j][k] = (matrix[i][j] === 1&& temp[i-1][j][k-1] && temp[i-1][j-1][k-1] && temp[i][j-1][k-1]) if(temp[i][j][k]){ count++; } } } } return count; };
实现:判断当前位置是否是边长为n的正方形,需要判断,在当前位置之前的边长为n的范围内是否全是1,是则说明是n正方形。
如何判断确定之前的正方形是否是1,主要判断,(i-1,j),(i-1,j-1),(i,j-1)是否是边长为n-1的正方形。
充分利用之前的计算结果。
dp[i][j][k] = (matrix[i][j] == 1 && dp[i - 1][j][k - 1] && dp[i][j - 1][k - 1] && dp[i - 1][j - 1] [k - 1]);
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-square-submatrices-with-all-ones
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。