📜  门| GATE-CS-2017(Set 2)|问题13(1)

📅  最后修改于: 2023-12-03 15:12:44.077000             🧑  作者: Mango

题目描述

给定一个只包含0和1的矩阵A,找到最大的正方形子矩阵,并返回该正方形的大小。

例如,对于以下矩阵

1 0 1 0 0 
1 0 1 1 1 
1 1 1 1 1 
1 0 0 1 0

最大的正方形子矩阵为

1 1 1
1 1 1
1 1 1

其大小为9。

请编写一个函数:

int maxSquareSubmatrix(vector<vector<int> > A);

函数参数:

  • A:包含0和1的二维矩阵(0 ≤ A[i][j] ≤1),保证行数和列数均不超过1000。

函数返回值:

  • 返回最大正方形子矩阵的大小(即正方形的边长)。
思路解析

本题可以使用动态规划的方法进行求解。

定义dp[i][j]表示以点(i,j)为右下角的最大正方形边长,那么对于dp[i][j]有以下状态转移方程:

dp[i][j] = min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]) + 1;

边界条件是当(i,j)为1时,dp[i][j]的初始值为1。

最终结果即dp数组中最大的值。

代码实现
int maxSquareSubmatrix(vector<vector<int> > A) {
    int n = A.size(), m = A[0].size();
    vector<vector<int>> dp(n, vector<int>(m, 0)); // 定义dp数组,初始化为0
    int ans = 0;
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            if(!A[i][j]) continue;
            dp[i][j] = 1;  // 边界条件
            if(i && j)
                dp[i][j] = min(dp[i-1][j], min(dp[i][j-1], dp[i-1][j-1])) + 1; // 状态转移方程
            ans = max(ans, dp[i][j]*dp[i][j]); // 更新最大值
        }
    }
    return ans;
}
复杂度分析

时间复杂度:$O(nm)$

空间复杂度:$O(nm)$

由于需要动态规划求解,所以时间和空间复杂度都是$O(nm)$。其中,$n$和$m$分别为矩阵的行数和列数。