剑指 Offer II 100. 三角形中最小路径之和

回溯

  1. 可以输出路径,但是会超时。

image.png

  1. class Solution {
  2. int res;
  3. public int minimumTotal(List<List<Integer>> triangle) {
  4. if (triangle == null || triangle.size() == 0) return 0;
  5. res = Integer.MAX_VALUE;
  6. // 移动到下一行中相邻的结点上
  7. // 当前层节点为 triangle[2][2],下一层相邻节点为 triangle[3][2]、triangle[3][3e]
  8. // 可以用回溯试试
  9. List<Integer> path = new ArrayList<>();
  10. backTracking(triangle, 0, 0, 0, path);
  11. return res;
  12. }
  13. private void backTracking(List<List<Integer>> tria, int level, int i, int pathSum, List<Integer> path) {
  14. if (level > tria.size()) return;
  15. if (level == tria.size()) {
  16. res = Math.min(res, pathSum);
  17. return;
  18. }
  19. pathSum += tria.get(level).get(i);
  20. path.add(tria.get(level).get(i));
  21. backTracking(tria, level + 1, i, pathSum, path);
  22. backTracking(tria, level + 1, i + 1, pathSum, path);
  23. pathSum -= tria.get(level).get(i);
  24. path.remove(path.size() - 1);
  25. }
  26. }

回溯 + 记忆化搜索

动态规划

  1. dp[i][j] 的含义表示从 点 (i, j) 到底边的最小路径和。
  2. 状态转换方程:dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + tria[i][j]
  1. class Solution {
  2. public int minimumTotal(List<List<Integer>> triangle) {
  3. if (triangle == null || triangle.size() == 0) return 0;
  4. int size = triangle.size();
  5. int[][] dp = new int[size + 1][size + 1];
  6. for (int i = size - 1; i >= 0; i--) {
  7. for (int j = 0; j <= i; j++) {
  8. dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle.get(i).get(j);
  9. }
  10. }
  11. return dp[0][0];
  12. }
  13. }