最大正方形
难度:
标签:
题目描述
在一个由 '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'
代码结果
运行时间: 99 ms, 内存: 30.3 MB
/*
* 思路:
* 我们使用动态规划来解决这个问题。定义一个二维dp数组,其中dp[i][j]表示以(i, j)为右下角的正方形的最大边长。
* 初始化时,矩阵的第一行和第一列的dp值等于矩阵的值。对于其他元素,如果矩阵值为'1',
* 则dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1,否则dp[i][j] = 0。
* 最后,遍历dp数组,找到最大的边长,并计算面积。
* 此处使用Java Stream API来简化代码。
*/
import java.util.Arrays;
public class SolutionStream {
public int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int rows = matrix.length, cols = matrix[0].length;
int[] dp = new int[cols + 1];
int maxSide = 0, prev = 0;
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= cols; j++) {
int temp = dp[j];
if (matrix[i - 1][j - 1] == '1') {
dp[j] = Math.min(Math.min(dp[j - 1], dp[j]), prev) + 1;
maxSide = Math.max(maxSide, dp[j]);
} else {
dp[j] = 0;
}
prev = temp;
}
}
return maxSide * maxSide;
}
}
解释
方法:
这道题使用动态规划来解决。定义二维dp数组,其中dp[i][j]表示以(i,j)为右下角的正方形的最大边长。状态转移方程为:当前位置如果为'1',则dp[i][j] = min(左上角dp值, 正上方dp值, 正左方dp值) + 1。最后返回dp数组中的最大值的平方即为最大正方形面积。
时间复杂度:
O(mn)
空间复杂度:
O(mn)
代码细节讲解
🦆
为什么状态转移方程中要取min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1,这里的min函数具体起到什么作用?
▷🦆
在题解中提到初始化第0行和第0列,如果整个矩阵的第一行或第一列全为'0',这种初始化方式是否还适用?
▷🦆
题解中未提及对于空矩阵输入的处理,如何修改代码以确保对于空矩阵的输入不会出现错误?
▷🦆
题解中使用了一个双层循环遍历整个矩阵,这种方法是否会处理所有边界情况,例如矩阵中全是'1'或全是'0'的情况?
▷相关问题
最大矩形
给定一个仅包含 0
和 1
、大小为 rows x cols
的二维二进制矩阵,找出只包含 1
的最大矩形,并返回其面积。
示例 1:

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] 输出:6 解释:最大矩形如上图所示。
示例 2:
输入:matrix = [["0"]] 输出:0
示例 3:
输入:matrix = [["1"]] 输出:1
提示:
rows == matrix.length
cols == matrix[0].length
1 <= row, cols <= 200
matrix[i][j]
为'0'
或'1'
最大加号标志
在一个 n x n
的矩阵 grid
中,除了在数组 mines
中给出的元素为 0
,其他每个元素都为 1
。mines[i] = [xi, yi]
表示 grid[xi][yi] == 0
返回 grid
中包含 1
的最大的 轴对齐 加号标志的阶数 。如果未找到加号标志,则返回 0
。
一个 k
阶由 1
组成的 “轴对称”加号标志 具有中心网格 grid[r][c] == 1
,以及4个从中心向上、向下、向左、向右延伸,长度为 k-1
,由 1
组成的臂。注意,只有加号标志的所有网格要求为 1
,别的网格可能为 0
也可能为 1
。
示例 1:
输入: n = 5, mines = [[4, 2]] 输出: 2 解释: 在上面的网格中,最大加号标志的阶只能是2。一个标志已在图中标出。
示例 2:
输入: n = 1, mines = [[0, 0]] 输出: 0 解释: 没有加号标志,返回 0 。
提示:
1 <= n <= 500
1 <= mines.length <= 5000
0 <= xi, yi < n
- 每一对
(xi, yi)
都 不重复