leetcode 120 三角形最小路径和

描述:

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。面试

例如,给定三角形:算法

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]
复制代码

自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。数组

说明:

若是你能够只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。bash

思路:

这里有两种方法能够进行求解测试

1 回溯法(枚举),找到每个值,而后返回,比较大小,找出最小值。(leetcode过不了,最后一个测试用例会超时)ui

2 动态规划:spa

  • 定义状态dp[i][j]:从底层到triange[i][j]的路径,找到最小值。
  • 状态转移方程:dp[i][j] = triangle[i][j] + min(dp[i+1][j],dp[i+1][j+1])。
  • 定义初始值:底层不变,逐步向上进行推动。

代码1:

class Solution {
  int min = Integer.MAX_VALUE;
  int sum = 0;

  public int minimumTotal(List<List<Integer>> triangle) {
    int i = 0, j = 0;
    helper(triangle, i, j);
    return min;
  }

  private void helper(List<List<Integer>> triangle, int i, int j) {
    if (i == triangle.size()) {
      min = Math.min(sum, min);
      return;
    }
    sum += triangle.get(i).get(j);
    helper(triangle, i + 1, j);
    helper(triangle, i + 1, j + 1);
    sum -= triangle.get(i).get(j);
  }
}
复制代码


结果1:

代码2:3d

class Solution {
  public int minimumTotal(List<List<Integer>> triangle) {
    int[] mini = new int[triangle.size() + 1];
    for (int i = triangle.size() - 1; i >= 0; i--) {
      for (int j = 0; j < triangle.get(i).size(); j++) {
        mini[j] = triangle.get(i).get(j) + Math.min(mini[j], mini[j + 1]);
      }
    }
    return mini[0];
  }
}
复制代码


结果2:code


总结:

回溯法,须要把整个数组的每一条路径都遍历一遍,时间复杂度是O(n的平方),最后一个测试用例会超时,可是也是一种解决问题的办法,面试的话也能够考虑使用,代码很是简洁,可读性比较强。cdn

动态规划这里用了一个小技巧,用一维数组去记录子问题的最优解,能够省一个维度的内存空间,代码也比较简洁。

相关文章
相关标签/搜索