## 题目描述
在一个由 `'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
```
解释:最大正方形的边长为2,面积为4。
---
## 解题思路
### 动态规划法
**核心思想**:
使用动态规划(Dynamic Programming)记录每个位置作为右下角时能构成的最大正方形的边长。
- 定义 `dp[i][j]` 表示以 `(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
\]
该方程的含义是:当前位置的边长由其上方、左方和左上方的三个位置的最小值决定,因为这三个方向共同限制了当前正方形的扩展能力。
**边界条件**:
- 当 `i == 0` 或 `j == 0`(即第一行或第一列)时,若 `matrix[i][j]` 为 `'1'`,则 `dp[i][j] = 1`。
**遍历过程**:
1. 初始化二维数组 `dp`,大小与原矩阵相同。
2. 遍历矩阵中的每个元素,根据上述规则填充 `dp` 数组。
3. 在遍历过程中,记录最大边长 `maxSquareSize`。
4. 最终返回 `maxSquareSize * maxSquareSize`(面积)。
---
## 代码实现
```java
public class MaximumSquare {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt(); // 行数
int n = sc.nextInt(); // 列数
sc.nextLine(); // 清除换行符
char[][] matrix = new char[m][n];
for (int i = 0; i < m; i++) {
String line = sc.nextLine();
for (int j = 0; j < n; j++) {
matrix[i][j] = line.charAt(j);
}
}
int maxSquareSize = maximalSquare(matrix);
System.out.println(maxSquareSize);
}
public static int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int rows = matrix.length;
int cols = matrix[0].length;
int[][] dp = new int[rows][cols];
int maxSquareSize = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; 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;
}
maxSquareSize = Math.max(maxSquareSize, dp[i][j]);
}
}
}
return maxSquareSize * maxSquareSize;
}
}
```
---
## 复杂度分析
- **时间复杂度**:O(mn),其中 m 和 n 分别为矩阵的行数和列数。
- **空间复杂度**:O(mn),需要额外的二维数组 `dp` 存储中间状态。
---
## 其他测试用例
### 测试用例1
**输入**:
```
1 5
11111
```
**输出**:1
**解释**:虽然所有元素都是 `'1'`,但最大正方形的边长为1(仅单个元素)。
### 测试用例2
**输入**:
```
3 3
111
111
111
```
**输出**:9
**解释**:整个矩阵构成一个3x3的正方形,面积为9。
---
## 总结
通过动态规划方法,能够高效地找到最大正方形的边长。其核心在于利用已计算的子问题结果(以某个位置为右下角的正方形边长),通过状态转移方程推导出更大问题的解。该方法避免了暴力枚举所有可能的正方形,显著降低了时间复杂度。