1277. Count Square Submatrices with All Ones 一个矩阵中有多少个正方形子矩阵

Given a m * n matrix of ones and zeros, return how many square submatrices have all ones.

Example 1:

Input: matrix =
[
  [0,1,1,1],
  [1,1,1,1],
  [0,1,1,1]
]
Output: 15
Explanation: 
There are 10 squares of side 1.
There are 4 squares of side 2.
There is  1 square of side 3.
Total number of squares = 10 + 4 + 1 = 15.

Example 2:

Input: matrix = 
[
  [1,0,1],
  [1,1,0],
  [1,1,0]
]
Output: 7
Explanation: 
There are 6 squares of side 1.  
There is 1 square of side 2. 
Total number of squares = 6 + 1 = 7.

 

Constraints:

  • 1 <= arr.length <= 300
  • 1 <= arr[0].length <= 300
  • 0 <= arr[i][j] <= 1

题意: 给出一个有0或1组成矩阵,0表示空,1表示一个子矩阵,求这个矩阵中有多少个正方形的矩阵。

思路:与题221. Maximal Square 最大正方形类似,先求出矩阵中每个单位能与左、上、左上形成的最大矩形,然后根据边长长的矩形包含了边长短的矩形的原理,即可求出总共有多少正方形矩阵。

例如某个单位能与左、上、左上单位组成边长为3矩阵,那也能组成一个边长为2和一个边长为1的矩阵。

代码:

class Solution {
    public int countSquares(int[][] matrix) {
        int row = matrix.length;
        int col = matrix[0].length;
        int[][] dp = new int[row+1][col+1];
        int sum = 0;
        for(int i=1;i<=row;i++){
            for(int j=1;j<=col;j++){
                if(matrix[i-1][j-1]==0)  
                    continue;
                //当前单位能与左、上、左上单位形成最大的正方形矩阵
                dp[i][j]= Math.min(dp[i-1][j-1],Math.min(dp[i-1][j],dp[i][j-1])) +1 ;
                for(int k=dp[i][j];k>0;k--){
                    //边长长的矩阵也包含了边长更短的矩阵
                    sum+=1;
                }
            }
        }
        return sum;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,作为AI语言模型,我没有办法为您提供完整的C代码。以下是一个基于multifrontal算法的稀疏矩阵的LU分解的伪代码,供您参考: 1. 定义一个结构体来存储稀疏矩阵的信息,包括矩阵的行数、列数、非零元素的数量、每行的第一个非零元素的位置等信息。 2. 为每个非零元素分配一个全局唯一的标识符,将其存储在一个哈希表中,以便后续操作时可以快速定位某个元素。 3. 构造多重前端树(multifrontal tree),将矩阵划分为多个子矩阵,并按照多重前端树的结构组织起来。 4. 对于每个子矩阵,使用高斯消元法进行LU分解,并记录下每个非零元素在L和U矩阵中的位置和值。 5. 将每个子矩阵的L和U矩阵合并起来,得到整个矩阵的LU分解。 6. 使用前向/后向代换算法求解方程组。 以下是伪代码的示例: //定义稀疏矩阵结构体 struct SparseMatrix { int nrows; //行数 int ncols; //列数 int nnz; //非零元素数量 int* rowptr; //每行的第一个非零元素的位置 int* colind; //每个非零元素所在的列号 double* data; //每个非零元素的值 }; //定义哈希表结构体 struct HashTable { int* keys; //标识符 int* vals; //索引 }; //构造多重前端树 void ConstructMultifrontalTree(SparseMatrix A, int num_levels) { //TODO: 实现多重前端树的构造 } //使用高斯消元法进行LU分解 void GaussianElimination(SparseMatrix A, int start_row, int end_row, int start_col, int end_col) { //TODO: 实现高斯消元法 } //将每个子矩阵的L和U矩阵合并起来 void MergeLUFactors(int num_levels) { //TODO: 实现L和U矩阵的合并 } //使用前向/后向代换算法求解方程组 void ForwardBackwardSubstitution(SparseMatrix L, SparseMatrix U, double* b, double* x) { //TODO: 实现前向/后向代换算法 } //主函数 int main() { //TODO: 读入稀疏矩阵A和向量b int num_levels = 3; //定义多重前端树的层数 ConstructMultifrontalTree(A, num_levels); //构造多重前端树 for (int level = 1; level <= num_levels; level++) { for (int i = 0; i < num_submatrices[level]; i++) { int start_row = submatrix_start_rows[level][i]; int end_row = submatrix_end_rows[level][i]; int start_col = submatrix_start_cols[level][i]; int end_col = submatrix_end_cols[level][i]; GaussianElimination(A, start_row, end_row, start_col, end_col); //对每个子矩阵进行LU分解 } } MergeLUFactors(num_levels); //将每个子矩阵的L和U矩阵合并起来 ForwardBackwardSubstitution(L, U, b, x); //使用前向/后向代换算法求解方程组 return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值