一.题目描述
在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。
输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:4
输入:matrix = [[“0”,“1”],[“1”,“0”]]
输出:1
输入:matrix = [[“0”]]
输出:0
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j] 为 ‘0’ 或 ‘1’
二.题目解析
1.动态规划
public int maximalSquare(char[][] matrix) {
/*动态规划
状态:dp[i][j]表示以第i行j列元素为右下角的只包含1的最大正方形边长
时间复杂度 O(height * width),空间复杂度O(height ∗ width)
* */
if(matrix == null || matrix.length == 0){
return 0;
}
int height = matrix.length;
int width = matrix[0].length;
//dp数组全都初始化为0
int[][] dp = new int[height][width];
int cur,max = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
cur = matrix[i][j] - '0';
if(i == 0 || j == 0){
//如果是第一行或者第一列的元素,以它为右下角的只包含1的最大正方形
dp[i][j] = cur == 1 ? 1 : 0;
}else if(cur == 1){
//如果当前元素为1,利用状态转移方程
//如果它的上方,左方和左上方为右下角的正方形的大小不一样,合起来就会缺了某个角落,所以要取这三个中最小的正方形边长+1
dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1],dp[i - 1][j]),dp[i][j - 1]) + 1;
}
//如果当前元素是0,dp值为0,又因为初始化就是0,所以无需再处理
//max不断保存更大的正方形边长
max = Math.max(max,dp[i][j]);
}
}
return max * max;
}
2.状态压缩
public int maximalSquare1(char[][] matrix) {
/*动态规划-状态压缩,由解法一可知每一列的计算只用到了上一列的结果,
我们可以用一维数组来代替二维数组
状态:dp[i]表示以某一列时的第i行元素为右下角的只包含1的最大正方形边长
时间复杂度 O(height * width),空间复杂度O(height)
* */
if(matrix == null || matrix.length == 0){
return 0;
}
int height = matrix.length;
int width = matrix[0].length;
//dp数组全都初始化为0
int[] dp = new int[height];
int cur,pre = 0,temp,max = 0;
//注意i代表列数,j代表行数
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
cur = matrix[j][i] - '0';
//第0列的计算不需要pre
if(i == 0 || j == 0){
dp[j] = cur == 1 ? 1 : 0;
}else{
//如果更新当前第j行的值,那么下一行的计算取左上角的值将被覆盖,所以需要先保存下
temp = dp[j];
//cur == 0时,一定要赋值为0,区别于二维数组无需赋值,因为一维dp数组会存在覆盖现象
dp[j] = cur == 1 ? Math.min(Math.min(pre, dp[j - 1]), dp[j]) + 1 : 0;
//更新pre
pre = temp;
}
max = Math.max(max,dp[j]);
}
//计算下一列时更新pre为dp数组第一个元素
pre = dp[0];
}
return max * max;
}
参考文章:
https://leetcode-cn.com/problems/maximal-square/solution/221-zui-da-zheng-fang-xing-tu-jie-shi-pin-yan-shi-/