1. 三角形最小路径和
(1)递归
每次只能移动到下一行中的相邻结点,求从顶点到底边的最小路径和。
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
相邻结点:与(i, j) 点相邻的结点为 (i + 1, j) 和 (i + 1, j + 1)。
若定义 f(i, j)f(i,j) 为 (i, j)(i,j) 点到底边的最小路径和,则易知递归求解式为:
f(i,j) = min(f(i + 1,j), f(i + 1, j + 1)) + triangle[i][j]
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
return dfs(triangle, 0, 0);
}
private int dfs(List<List<Integer>> triangle, int i, int j) {
if (i == triangle.size()) {
return 0;
}
return Math.min(dfs(triangle, i + 1, j), dfs(triangle, i + 1, j + 1)) + triangle.get(i).get(j);
}
}
(2)递归优化
- 直接递归暴力搜索会有大量重复计算,所以会超时
- 在解法一的基础上,定义了二维数组进行记忆化。
- 时间复杂度:O(N^2) ,N 为三角形的行数。
空间复杂度:O(N^2),NN 为三角形的行数。
class Solution {
//使用Integer数组是为了判断数组某个位置是否存在值
Integer[][] memo;
public int minimumTotal(List<List<Integer>> triangle) {
memo = new Integer[triangle.size()][triangle.size()];
return dfs(triangle, 0, 0);
}
private int dfs(List<List<Integer>> triangle, int i, int j) {
if (i == triangle.size()) {
return</