0x01.问题
在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。
示例:
输入:
1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0
输出: 4
public int maximalSquare(char[][] matrix)
0x02.dp的简要分析
-
问题的关键是在矩阵中找一个只包含1的最大正方形。
-
根据普通的思路,可以暴力的去搜索,每遇到
1
,就把这个1
当做正方形的左上角,去搜索这个正方形,但是需要考虑的情况有些复杂,时间消耗的也较多。 -
在矩阵中搜索正方形,其实可以分解为无数个互不相关的子问题,于是可以考虑使用dp。
-
-
dp思路的思考:
- 状态:
dp[i][j]
表示以[i][j]
为右下角,且只包含1
的正方形的边长最大值。 - 转移方程:
dp[i][j]=min{dp[i-1][j],dp[i][j-1],dp[i-1][j-1]}+1
。取左边,上边,左上角的最小值加1。 - 初始条件,若
(i==0||j==0)&&matrix[i][j]=='1'
,那么dp[i][j]=1
。
- 状态:
-
维护
maxSide
:- 在每次计算完一次
dp
后,maxSide=max{maxSide,dp[i][j]}
。 - 最终的答案是
maxSide*maxSide
。
- 在每次计算完一次
0x03.解决代码
class Solution {
public int maximalSquare(char[][] matrix) {
int maxSide=0;
if(matrix==null||matrix.length==0||matrix[0].length==0){
return maxSide;
}
int m=matrix.length;
int n=matrix[0].length;
int[][] dp=new int[m][n];
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(matrix[i][j]=='1'){
if(i==0||j==0){
dp[i][j]=1;
}else{
dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
}
maxSide=Math.max(dp[i][j],maxSide);
}
}
}
return maxSide*maxSide;
}
}
ATFWUS --Writing By 2020–05-08