#### 题目描述
给定一个 `n x n` 的方形整数数组 `matrix`,找到从第一行任意元素开始,每一步移动到下一行相邻列(正下方、左下或右下)的路径,使得路径和最小。
#### 方法思路
**动态规划**:从倒数第二行开始逐层向上计算每个位置的最小路径和。每个位置的最小和等于当前值加上下一行相邻三个元素的最小值。最终,第一行的最小值即为答案。
#### 代码实现
```java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] matrix = new int[n][n];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = sc.nextInt();
}
}
System.out.println(minFallingPathSum(matrix));
}
public static int minFallingPathSum(int[][] matrix) {
int n = matrix.length;
// 从倒数第二行开始向上递推
for (int i = n - 2; i >= 0; i--) {
for (int j = 0; j < n; j++) {
int current = matrix[i][j];
// 处理边界,用三元运算符避免越界
int left = (j > 0) ? matrix[i + 1][j - 1] : Integer.MAX_VALUE;
int mid = matrix[i + 1][j];
int right = (j < n - 1) ? matrix[i + 1][j + 1] : Integer.MAX_VALUE;
// 更新当前值的最小路径和
matrix[i][j] = current + Math.min(left, Math.min(mid, right));
}
}
// 遍历第一行找最小值
int minSum = Integer.MAX_VALUE;
for (int num : matrix[0]) {
minSum = Math.min(minSum, num);
}
return minSum;
}
}
```
#### 新知识点解析
1. **三元运算符**:
用于简化条件判断,如 `int left = (j > 0) ? ... : ...`,避免了局部变量的复杂判断,代码更简洁。
2. **边界处理**:
当处理首列或末列时,通过 `Integer.MAX_VALUE` 标记无效路径,确保取最小值时自动排除越界情况。
3. **原地修改数组**:
动态规划直接修改原数组,节省空间复杂度。由于计算顺序是从下到上,不会覆盖未处理的值。
#### 常见错误点
- **数组越界**:处理列边界时需用三元运算符严谨判断,避免访问 `j-1` 或 `j+1` 越界。
#### 复杂度分析
- **时间复杂度**:O(n²),遍历每个元素一次。
- **空间复杂度**:O(1),直接在原数组上修改。
通过逐层递推和合理处理边界,能够高效求解下降路径的最小和。