1.三角形最小路径和
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
例如,给定三角形:
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
自顶向下的最小路径和为 11
(即,2 + 3 + 5 + 1 = 11)。
说明:
如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。
题解:如果是使用贪心从上到下每一步都选择下一步中较小的那个数值并求和,最后的结果不一定是最优的,所以针对本题应该是从下到上,先确定最后一步的最小和,然后依次往上。使用动规解决。
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
int m=triangle.size();
int[] dp=new int[m+1];
for(int i=0;i<m;i++)
dp[i]=triangle.get(m-1).get(i);
for(int i=m-2;i>=0;i--){
for(int j=0;j<=i;j++){
dp[j]=Math.min(dp[j],dp[j+1])+triangle.get(i).get(j);
}
}
return dp[0];
}
}
2.最小路径和
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小。
题解:思路与上题基本相同,这里注意数组压缩的问题就行了。
class Solution {
public int minPathSum(int[][] grid) {
if(grid==null)
return 0;
int m=grid.length;
int n=grid[0].length;
int[] dp=new int[n];
dp[0]=grid[0][0];
for(int j=1;j<n;j++)
dp[j]=dp[j-1]+grid[0][j];
for(int i=1;i<m;i++){
dp[0]=dp[0]+grid[i][0];
for(int j=1;j<n;j++){
dp[j]=Math.min(dp[j],dp[j-1])+grid[i][j];
}
}
return dp[n-1];
}
}