题目
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
说明:
如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。
解题思路
上一行的点index只能走下一行的index和index+1这2个下标,所以自底向上的做法来维护一个dp数组,可以得出dp[index] = Math.min(dp[index], dp[index+1]) + list.get(index);
下一行的点index只能走上一行的 index-1和index,所以自顶向下的做法可得出dp[index] = Math.min(dp[index-1], dp[index]) + list.get(index);
代码如下
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
/**
* 自顶向下
*/
int size = triangle.size();
if(size == 0) return 0;
int[] dp = new int[size];
dp[0] = triangle.get(0).get(0);
//排除后面的数据的干扰
for(int i = 1; i < size; i ++) {
dp[i] = Integer.MAX_VALUE;
}
for(int i = 1; i < size; i ++) {
List<Integer> list = triangle.get(i);
//dp改变后对后面的数据有影响
int[] tmp = Arrays.copyOf(dp, size);
for(int j = 0; j <= i; j ++) {
dp[j] = list.get(j) + (j-1>=0 ? Math.min(tmp[j-1], tmp[j]) : tmp[j]);
}
}
//不知道最小的值在哪里 仍需要再遍历一遍数组
int res = Integer.MAX_VALUE;
for(int i = 0; i < size; i ++) {
res = Math.min(dp[i], res);
}
return res;
/**
* 自底向上的做法
* 直接从后面走到最上面解决
*/
/*int size = triangle.size();
if(size == 0) return 0;
int[] dp = new int[size];
List<Integer> list = triangle.get(size-1);
for(int i = 0; i < size; i ++) {
dp[i] = list.get(i);
}
for(int i = size-2; i >= 0; i --) {
list = triangle.get(i);
for(int j = 0; j <= i; j ++) {
dp[j] = Math.min(dp[j], dp[j+1]) + list.get(j);
}
}
return dp[0];*/
}
}
提交结果
成功
显示详情
执行用时 : 4 ms, 在Triangle的Java提交中击败了95.80% 的用户
内存消耗 : 35.4 MB, 在Triangle的Java提交中击败了95.85% 的用户