题目链接

三角形最小路径和

题目描述

image.png

实现代码

初次代码采用dfs的思想实现,每层元素只有两个选择:取或者不取,而从当前位置往下又有两个选择,取左边和去右边,因此,针对这两个选择进行dfs递归实现;

代码如下,结果超时:

  1. package ccnu.agile.jdk8;
  2. import ccnu.agile.utils.JSONUtils;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. /**
  6. * @Description:
  7. * @Author: JreamY
  8. * @Date: 2022/2/25
  9. **/
  10. public class Demo {
  11. int result = Integer.MAX_VALUE;
  12. public static void main(String[] args) {
  13. List<List<Integer>> triangle = new ArrayList<>();
  14. List<Integer> list1= new ArrayList<>();
  15. list1.add(2);
  16. List<Integer> list2 = new ArrayList<>();
  17. list2.add(3);
  18. list2.add(4);
  19. List<Integer> list3 = new ArrayList<>();
  20. list3.add(6);
  21. list3.add(5);
  22. list3.add(7);
  23. List<Integer> list4 = new ArrayList<>();
  24. list4.add(4);
  25. list4.add(1);
  26. list4.add(8);
  27. list4.add(3);
  28. triangle.add(list1);
  29. triangle.add(list2);
  30. triangle.add(list3);
  31. triangle.add(list4);
  32. System.out.println(new Demo().minimumTotal(triangle));
  33. }
  34. public int minimumTotal(List<List<Integer>> triangle) {
  35. dfs(triangle, 1, 0, triangle.get(0).get(0), triangle.size());
  36. return result;
  37. }
  38. public void dfs(List<List<Integer>> triangle, int layer, int curIdx, int res, int size) {
  39. if(layer == size+1) {
  40. return;
  41. }
  42. if(layer == size) {
  43. result = Math.min(result, res);
  44. return;
  45. }
  46. dfs(triangle, layer+1, curIdx, res+triangle.get(layer).get(curIdx), size);
  47. dfs(triangle, layer+1, curIdx+1, res+triangle.get(layer).get(curIdx+1), size);
  48. }
  49. }

参考官方动态规划思想:记数组dp[i][j]表示从顶点出发到第i行j列位置的最短路径值,由三角形的特性可以知道:dp[i][j]的值只与dp[i-1][j]和dp[i-1][j-1]有关,其状态转移方程如下:

dp[i][j] = min(dp[i-1][j], dp[i-1][j-1]) + c[i][j]

同时考虑边界条件:

  1. dp[0][0] = c[0][0];
  2. 对于j=0的数据,dp[i][j] = dp[i-1][j] + c[i][j];
  3. 对于i == j的数据,dp[i][j] = dp[i-1][j-1] + c[i][j];

代码如下:

  1. class Solution {
  2. public int minimumTotal(List<List<Integer>> triangle) {
  3. // dfs(triangle, 1, 0, triangle.get(0).get(0), triangle.size());
  4. // return result;
  5. int len = triangle.size();
  6. int[][] dp = new int[len][len]; // 顶部到第ij列位置的最短路径和
  7. // 初始化边界条件
  8. dp[0][0] = triangle.get(0).get(0);
  9. for (int i = 1; i < len; i++) {
  10. for (int j = 0; j < i+1; j++) {
  11. if(j == 0) {
  12. dp[i][j] = dp[i-1][j] + triangle.get(i).get(j);
  13. continue;
  14. }
  15. if(i == j) {
  16. dp[i][j] = dp[i-1][j-1] + triangle.get(i).get(j);
  17. continue;
  18. }
  19. dp[i][j] = Math.min(dp[i - 1][j], dp[i - 1][j - 1]) + triangle.get(i).get(j);
  20. }
  21. }
  22. int min = dp[len-1][0];
  23. for (int i = 1; i < len; i++) {
  24. if (dp[len-1][i] < min) {
  25. min = dp[len-1][i];
  26. }
  27. }
  28. return min;
  29. }
  30. }