题目描述:
在一个由 '0' 和 '1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积。
示例 1:
输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:4
示例 2:
输入:matrix = [["0","1"],["1","0"]]
输出:1
示例 3:输入:matrix = [["0"]]
输出:0
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j] 为 '0' 或 '1'来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximal-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析:
这道题我不怎么会,想到了dfs和bfs,但是显然不怎么好使。没办法,就去看了题解。原来是一道动归题目。
dp[i][j]代表以matrix[i][j]为右下角顶点的最大正方形的边长,如果matrix[i][j]==‘0’,则 无法钩沉正方形,dp[i][j]=0。如果matrix[i][j]==‘1’,则构成的最大正方形的边长为:
dp[i][j]=min( dp[i-1][j] , dp[i][j-1] , dp[i-1][j-1] ) + 1
相关分析和证明请看题解:
代码如下:
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
// dp[i][j]代表以matrix[i][j]为右下角的最大正方形的边长
int dp[305][305];
int m=matrix.size();
if(m==0) return 0;
int n=matrix[0].size();
// max用来记录最大边长
int max=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(matrix[i][j]=='1')
{
// matrix[i][j]=='1'且左边或者上边为边界,只能形成边长为1的正方形
if(i-1<0||j-1<0) dp[i][j]=1;
// 左边或者上边不为边界,则根据递推式求出最大边长
else
dp[i][j]=min(dp[i-1][j],min(dp[i][j-1],dp[i-1][j-1]))+1;
}
// matrix[i][j]=='0'说明该位置无法构成正方形
else
dp[i][j]=0;
if(dp[i][j]>max)
max=dp[i][j];
}
}
return max*max;
}
};