回溯
- 可以输出路径,但是会超时。

class Solution { int res; public int minimumTotal(List<List<Integer>> triangle) { if (triangle == null || triangle.size() == 0) return 0; res = Integer.MAX_VALUE; // 移动到下一行中相邻的结点上 // 当前层节点为 triangle[2][2],下一层相邻节点为 triangle[3][2]、triangle[3][3e] // 可以用回溯试试 List<Integer> path = new ArrayList<>(); backTracking(triangle, 0, 0, 0, path); return res; } private void backTracking(List<List<Integer>> tria, int level, int i, int pathSum, List<Integer> path) { if (level > tria.size()) return; if (level == tria.size()) { res = Math.min(res, pathSum); return; } pathSum += tria.get(level).get(i); path.add(tria.get(level).get(i)); backTracking(tria, level + 1, i, pathSum, path); backTracking(tria, level + 1, i + 1, pathSum, path); pathSum -= tria.get(level).get(i); path.remove(path.size() - 1); }}
回溯 + 记忆化搜索
动态规划
dp[i][j] 的含义表示从 点 (i, j) 到底边的最小路径和。- 状态转换方程:
dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + tria[i][j]
class Solution { public int minimumTotal(List<List<Integer>> triangle) { if (triangle == null || triangle.size() == 0) return 0; int size = triangle.size(); int[][] dp = new int[size + 1][size + 1]; for (int i = size - 1; i >= 0; i--) { for (int j = 0; j <= i; j++) { dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle.get(i).get(j); } } return dp[0][0]; }}