作者:刺猬xiaojie | 来源:互联网 | 2024-11-05 12:06
题目要求在给定的m×n矩阵中,计算并返回所有完全由1组成的正方形子矩阵的数量。矩阵中的每个元素只能是0或1。通过动态规划的方法,可以高效地解决这一问题。示例中,输入矩阵包含多个由1组成的正方形子矩阵,需要统计这些子矩阵的总数。
1. 题目
给你一个 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 <&#61; arr.length <&#61; 300
1 <&#61; arr[0].length <&#61; 300
0 <&#61; arr[i][j] <&#61; 1
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
链接&#xff1a;https://leetcode-cn.com/problems/count-square-submatrices-with-all-ones
著作权归领扣网络所有。商业转载请联系官方授权&#xff0c;非商业转载请注明出处。
2. 解题
类似题目&#xff1a;
LeetCode 1504. 统计全 1 子矩形&#xff08;记录左侧的连续1的个数&#xff09;
LeetCode 5655. 重新排列后的最大子矩阵&#xff08;前缀和&#43;排序&#xff09;
dp[i][j]
表示 以(i,j)
为右下角的最大正方形边长- 第一行、第一列肯定最大是1&#xff08;矩阵值为1的话&#xff09;
- 其他为 1 位置的最大边长跟它相邻的几块的关系&#xff1a;等于左上方向3个最短的边长&#43;1
- 正方形的个数等于最大的边长
class Solution {
public:int countSquares(vector<vector<int>>& matrix) {int m &#61; matrix.size(), n &#61; matrix[0].size(), i, j, count &#61; 0;vector<vector<int>> dp(m,vector<int>(n,0));for(i &#61; 0; i < m; &#43;&#43;i){for(j &#61; 0; j < n; &#43;&#43;j){if(i&#61;&#61;0 || j&#61;&#61;0)dp[i][j] &#61; matrix[i][j];else if(matrix[i][j]&#61;&#61;1)dp[i][j] &#61; 1&#43;min(dp[i-1][j],min(dp[i][j-1],dp[i-1][j-1]));count &#43;&#61; dp[i][j];}}return count;}
};
另评论区Gremist
优化了内存&#xff0c;原地算法
class Solution {
public:int countSquares(vector<vector<int>>& matrix) {int ans &#61; 0;for (int i &#61; 0; i < matrix.size(); i&#43;&#43;) {for (int j &#61; 0; j < matrix[0].size(); j&#43;&#43;) {if (i && j && matrix[i][j]) {matrix[i][j] &#43;&#61; min({matrix[i-1][j-1], matrix[i-1][j], matrix[i][j-1]});}ans &#43;&#61; matrix[i][j];}}return ans;}
};