目录
题目链接:三角形_牛客题霸_牛客网 (nowcoder.com)
动态规划
1.自顶向下
问题分析:
“每一步都可以移动到下面一行相邻的数字”
动归五部曲
1.dp数组定义
dp[i][j]:从(0,0)-->(i,j)的最小路径和
2.递推公式
dp[i][j]=min(dp[i-1][j],dp[i-1][j-1])+arr[i][j]
j==0的那一列:dp[i][0]=dp[i-1][0]+arr[i][0]
j==i的那一列:dp[i][j]=dp[i-1][j-1]+arr[i][j]
3.初始化
dp[0][0]=arr[0][0]
4.遍历顺序
从上到下,从左到右
5.打印
代码如下:
public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) {
if (triangle.size() == 0) {
return 0;
}
int[][] dp=new int[triangle.size()][triangle.size()]; //dp数组创建
dp[0][0]=triangle.get(0).get(0); //初始化
for(int i=1;i<triangle.size();i++){
for(int j=0;j<=i;j++){
if(j==0){
//最左边一列
dp[i][0]=triangle.get(i).get(0)+dp[i-1][0];
}else if(j==i){
//最右边一列
dp[i][j]=triangle.get(i).get(j)+dp[i-1][j-1];
}else{
//非边界
dp[i][j]=Math.min(dp[i-1][j],dp[i-1][j-1])+triangle.get(i).get(j);
}
}
}
//找到最后一行最小的那个数
int minSum=Integer.MAX_VALUE;
for(int j=0;j<triangle.size();j++){
if(dp[triangle.size()-1][j]<minSum){
minSum=dp[triangle.size()-1][j];
}
}
return minSum;
}
2.自下向上
动归五部曲
1.dp数组定义
(i,j)到达最后一行的最小路径和
2.递推公式
dp[i][j]=min(dp[i+1][j],dp[i+1][j+1])+arr[i][j]
3.初始化
初始化dp数组的最后一行
4.遍历顺序
从下到上,从左到右
5.打印
分析:
代码如下:
public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) {
int len=triangle.size();
if(len==0){
return 0;
}
int[][] dp=new int[len][len]; //创建dp数组
//初始化
for(int j=0;j<len;j++){
dp[len-1][j]=triangle.get(len-1).get(j);
}
for(int i=len-2;i>=0;i--){
for(int j=0;j<=i;j++){
dp[i][j]=Math.min(dp[i+1][j],dp[i+1][j+1])+triangle.get(i).get(j);
}
}
return dp[0][0];
}