【问题描述】[第221题][最大正方形][中等]
在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大/长方形正方形,并返回其面积。示例:输入: 1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
长方形 输出: 6
正方形 输出: 4
【解答思路】
1. 长方形 暴力
时间复杂度:O(N^2) 空间复杂度:O(N^2)
public int maximalRectangle(char[][] matrix
) {if (matrix
.length
== 0) {return 0;}int[][] width
= new int[matrix
.length
][matrix
[0].length
];int maxArea
= 0;for (int row
= 0; row
< matrix
.length
; row
++) {for (int col
= 0; col
< matrix
[0].length
; col
++) {if (matrix
[row
][col
] == '1') {if (col
== 0) {width
[row
][col
] = 1;} else {width
[row
][col
] = width
[row
][col
- 1] + 1;}} else {width
[row
][col
] = 0;}int minWidth
= width
[row
][col
];for (int up_row
= row
; up_row
>= 0; up_row
--) {int height
= row
- up_row
+ 1;minWidth
= Math
.min(minWidth
, width
[up_row
][col
]);maxArea
= Math
.max(maxArea
, height
* minWidth
);}}}return maxArea
;
}
2. 正方形 暴力
- 正方形的面积是边长乘边长, maxArea 是没有意义的-- 只记录最大边长即可。然后是其它细节的修改,让代码更简洁,代码如下。
时间复杂度:O(N^2) 空间复杂度:O(N^2)
public int maximalSquare(char[][] matrix
) {if (matrix
.length
== 0) {return 0;}int[][] width
= new int[matrix
.length
][matrix
[0].length
];int maxSide
= 0;for (int row
= 0; row
< matrix
.length
; row
++) {for (int col
= 0; col
< matrix
[0].length
; col
++) {if (matrix
[row
][col
] == '1') {if (col
== 0) {width
[row
][col
] = 1;} else {width
[row
][col
] = width
[row
][col
- 1] + 1;}} else {width
[row
][col
] = 0;}int curWidth
= width
[row
][col
];for (int up_row
= row
; up_row
>= 0; up_row
--) {int height
= row
- up_row
+ 1;if (width
[up_row
][col
] <= maxSide
|| height
> curWidth
) {break;}maxSide
= Math
.max(height
, maxSide
);}}}return maxSide
* maxSide
;
}
2. 正方形 动态规划
第 1 步:设计状态
dp[i][j] 表示以 matrix[i][j] 为右下角正方形的最大边长
第 2 步:状态转移方程
dp[i][j] = Min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]) + 1
当前点的左边,上边,左上角的三个点中选一个最小值,然后加 1
第 3 步:考虑初始化
第一行和第一列的 dp[i][j] = matrix[i][j] - ‘0’,也就意味着 dp[i][j] 要么是 0 要么是 1
第 4 步:考虑输出
第 5 步:考虑是否可以状态压缩
时间复杂度:O(N^2) 空间复杂度:O(N)
public int maximalSquare(char[][] matrix
) {int rows
= matrix
.length
;if (rows
== 0) {return 0;}int cols
= matrix
[0].length
;int[][] dp
= new int[rows
+ 1][cols
+ 1];int maxSide
= 0;for (int i
= 1; i
<= rows
; i
++) {for (int j
= 1; j
<= cols
; j
++) {if (matrix
[i
- 1][j
- 1] == '0') {dp
[i
][j
] = 0;} else {dp
[i
][j
] = Math
.min(dp
[i
- 1][j
], Math
.min(dp
[i
][j
- 1], dp
[i
- 1][j
- 1])) + 1;maxSide
= Math
.max(dp
[i
][j
], maxSide
);}}}return maxSide
* maxSide
;
}
【总结】
1.动态规划流程
第 1 步:设计状态
第 2 步:状态转移方程
第 3 步:考虑初始化
第 4 步:考虑输出
第 5 步:考虑是否可以状态压缩
- 二维数组 -> 一维数组
2. 行 row 列 col 注意边界!
int rows = matrix.length;
nt cols = matrix[0].length;
3. 暴力 ->优化
转载链接:https://leetcode-cn.com/problems/maximal-square/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–46/
参考链接:https://leetcode-cn.com/problems/maximal-square/solution/li-jie-san-zhe-qu-zui-xiao-1-by-lzhlyle/
总结
以上是生活随笔为你收集整理的[Leedcode][JAVA][第85题][第221题][最大正方形][动态规划]的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。