- 下降路径最小和
给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径 的 最小和 。
下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。
示例 1:
输入:matrix = [[2,1,3],[6,5,4],[7,8,9]]
输出:13
解释:如图所示,为和最小的两条下降路径
示例 2:
输入:matrix = [[-19,57],[-40,-5]]
输出:-59
解释:如图所示,为和最小的下降路径
public int minFallingPathSum(int[][] matrix) {
int len = matrix.length;
int[][] dp = new int[len][len];
for (int i = 0; i < len; i++) {
dp[0][i] = matrix[0][i];
}
for (int i = 1; i < len; i++) {
dp[i][0] = Math.min(dp[i - 1][0], dp[i - 1][1]) + matrix[i][0];
for (int j = 1; j < len - 1; j++) {
dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]) + matrix[i][j];
}
dp[i][len - 1] = Math.min(dp[i - 1][len - 2], dp[i - 1][len - 1]) + matrix[i][len - 1];
}
int minans = Integer.MAX_VALUE;
for (int i = 0; i < len; i++) {
minans = Math.min(dp[len - 1][i], minans);
}
return minans;
}
- 三角形最小路径和
给定一个三角形 triangle ,找出自顶向下的最小路径和。
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。
示例 1:
输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
输出:11
解释:如下面简图所示:
2
3 4
6 5 7
4 1 8 3
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
示例 2:
输入:triangle = [[-10]]
输出:-10
public int minimumTotal(List<List<Integer>> triangle) {
int len=triangle.size();
int dp[][]=new int[len][len];
dp[0][0]=triangle.get(0).get(0);
for (int i = 1; i < len; i++) {
dp[i][0]=dp[i-1][0]+triangle.get(i).get(0);
for (int j = 1; j < i; j++) {
dp[i][j]=Math.min(dp[i-1][j-1],dp[i-1][j])+triangle.get(i).get(j);
}
dp[i][i]=dp[i-1][i-1]+triangle.get(i).get(i);
}
int result=Integer.MAX_VALUE;
for (int i = 0; i < len; i++) {
result=Math.min(dp[len-1][i],result);
}
return result;
}
- 不同路径
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7
输出:28
示例 2:
输入:m = 3, n = 2
输出:3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
- 向右 -> 向下 -> 向下
- 向下 -> 向下 -> 向右
- 向下 -> 向右 -> 向下
示例 3:
输入:m = 7, n = 3
输出:28
示例 4:
输入:m = 3, n = 3
输出:6
public int uniquePaths(int m, int n) {
int dp[][]=new int[m][n];
for (int i = 0; i < m; i++) {
dp[i][0]=1;
}
for (int i = 0; i < n; i++) {
dp[0][i]=1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
- 不同路径 II
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
示例 1:
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
- 向右 -> 向右 -> 向下 -> 向下
- 向下 -> 向下 -> 向右 -> 向右
示例 2:
输入:obstacleGrid = [[0,1],[0,0]]
输出:1
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int dp[][] = new int[m][n];
for (int i = 0; i < m; i++) {
if (obstacleGrid[i][0] == 1) {
dp[i][0] = 0;
break;
} else {
dp[i][0] = 1;
}
}
for (int i = 0; i < n; i++) {
if (obstacleGrid[0][i] == 1) {
dp[0][i] = 0;
break;
}
dp[0][i] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (obstacleGrid[i][j] == 1) {
dp[i][j] = 0;
} else {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m - 1][n - 1];
}
- 最小路径和
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例 1:
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。
示例 2:
输入:grid = [[1,2,3],[4,5,6]]
输出:12
public int minPathSum(int[][] grid) {
int m=grid.length;
int n=grid[0].length;
int dp[][]=new int[m][n];
dp[0][0]=grid[0][0];
for (int i = 1; i < m; i++) {
dp[i][0]=dp[i-1][0]+grid[i][0];
}
for (int i = 1; i < n; i++) {
dp[0][i]=dp[0][i-1]+grid[0][i];
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j]=Math.min(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}
return dp[m-1][n-1];
}