难度

  • 简单
  • 中等
  • 困难

    标签

    动态规划

    题目描述

    给定一个三角形 triangle ,找出自顶向下的最小路径和。

每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。

示例1:

  1. 输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
  2. 输出:11
  3. 解释:如下面简图所示:
  4. 2
  5. 3 4
  6. 6 5 7
  7. 4 1 8 3
  8. 自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

示例2:

  1. 输入:triangle = [[-10]]
  2. 输出:-10

提示:

  • 1 <= triangle.length <= 200
  • triangle[0].length == 1
  • triangle[i].length == triangle[i - 1].length + 1
  • -104 <= triangle[i][j] <= 104

    题解

    每个点的最小路径和,依赖于其上一行的相同位置和前一位置 即

    1. dp[i][j] = Math.min(dp[i - 1][j], dp[i - 1][j - 1]) + curVal;
    2. ps:需要处理最右边界的点的问题,因为每一行的最右边界,他的上一行相同位置是无的。
    3. 所以在最右边界时,dp[i][j] = dp[i - 1][j - 1] + curVal
    4. 又因为最右边界的index = iso dp[i][i] = dp[i - 1][i - 1] + curVal
    1. class Solution {
    2. // dp[i][j] = Math.min(dp[i - 1][j], dp[i - 1][j - 1]) + curVal;
    3. public int minimumTotal(List<List<Integer>> triangle) {
    4. int row = triangle.size();
    5. int col = triangle.get(row - 1).size();
    6. int[][] dp = new int[row][col];
    7. dp[0][0] = triangle.get(0).get(0);
    8. // 初始化第一列
    9. for(int i = 1; i < row; i++) {
    10. dp[i][0] = dp[i - 1][0] + triangle.get(i).get(0);
    11. }
    12. for(int i = 1; i < row; i++) {
    13. for(int j = 1; j < i; j ++){
    14. dp[i][j] = Math.min(dp[i - 1][j], dp[i - 1][j - 1]) + triangle.get(i).get(j);
    15. }
    16. // 最右边界处理
    17. dp[i][i] = dp[i - 1][i - 1] + triangle.get(i).get(i);
    18. }
    19. int min = dp[row - 1][0];
    20. for(int i = 1; i < col; i++) {
    21. min = Math.min(min, dp[row - 1][i]);
    22. }
    23. return min;
    24. }
    25. }