题目链接
题目分析
这个题要求我们在一个形状类似三角形的二维数组中寻找一条最短的路径,那么这个题暴力用bfs做是绝对会TLE的,所以只能用记忆化的方式。
对于记忆化的方式也有两种,第一种是自顶向下,第二种是自底向上。感觉DP就是怎么顺手怎么写就行了。
实现思路1
我们先开一个二维DP数组,dp[i][j]是到达第i层的第j个数的最短路径。做的时候我们反向做会比较好思考。
首先我们先把最底层的数据初始化,就是三角形最下面那一行的数据,然后我们在逐层往上走,对应的转移方程如下
- dp[i][j] = Math.min(dp[i+1][j], dp[i+1][j+1]) + temp.get(i);
temp是当前行的数组,因为我们可以很容易的知道当前位置的最小值受限于其左下角和右下角的数据,所以直接使用j下标访问即可。
最后我们返回dp[0][0],因为顶尖只有一条路可走。
实现思路2
考虑到这个题目有个加分项,我们可以考虑把二维数组压缩成一维数组,我们每次在修改数据之前用一个pre变量保存下修改前的数据即可。
代码实现
代码一
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
int[][] dp = new int[triangle.size()][triangle.get(triangle.size()-1).size()];
for(int i = 0; i < dp[0].length; i++){
dp[dp.length-1][i] = triangle.get(triangle.size() - 1).get(i);
}
for(int i = triangle.size()-2; i>= 0; i--){
List<Integer> temp = triangle.get(i);
for(int j = 0; j < temp.size(); j++){
dp[i][j] = Math.min(dp[i+1][j], dp[i+1][j+1]) + temp.get(j);
}
}
return dp[0][0];
}
}
代码二
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
int[] dp = new int[triangle.get(triangle.size()-1).size()];
for(int i = 0; i < dp.length; i++){
dp[i] = triangle.get(triangle.size() - 1).get(i);
}
int pre = -1;
for(int i = triangle.size() - 2; i >= 0; i--){
List<Integer> temp = triangle.get(i);
for(int j = 0; j < temp.size(); j++){
pre = dp[j];
dp[j] = Math.min(pre, dp[j+1]) + temp.get(j);
}
}
return dp[0];
}
}