最小路径和
来源:力扣(LeetCode) 链接:leetcode.cn/problems/mi…
给定一个包含非负整数的 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
提示:
- m == grid.length
- n == grid[i].length
- 1 <= m, n <= 200
- 0 <= grid[i][j] <= 100
代码
class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
// 创建一个二维数组dp,用于存储到达每个位置的最小路径和
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 j = 1; j < n; j++) {
dp[0][j] = dp[0][j-1] + grid[0][j];
}
// 动态规划求解最小路径和
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];
}
}
思路分析
- 创建一个二维数组
dp,其中dp[i][j]表示从起点到达位置(i, j)的最小路径和。 - 初始化第一行和第一列的最小路径和。第一行的最小路径和等于前一个位置的最小路径和加上当前位置的值,第一列的最小路径和等于上一个位置的最小路径和加上当前位置的值。
- 使用动态规划的方法计算剩余位置的最小路径和。对于位置
(i, j),最小路径和等于上方位置的最小路径和和左方位置的最小路径和中的较小值加上当前位置的值。 - 最终,返回
dp[m-1][n-1],即右下角位置的最小路径和。
爬楼梯
来源:力扣(LeetCode) 链接:leetcode.cn/problems/cl…
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
提示:
- 1 <= n <= 45
代码
class Solution {
public int climbStairs(int n) {
if (n <= 2) {
return n;
}
int[] dp = new int[n+1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
}
思路分析
- 使用动态规划的思想,创建一个长度为n+1的数组
dp,其中dp[i]表示爬到第i个台阶的方法数。 - 初始化
dp[1] = 1,表示爬到第1个台阶只有1种方法。 - 初始化
dp[2] = 2,表示爬到第2个台阶有2种方法:一次爬2个台阶或分两次爬1个台阶。 - 对于第i个台阶,可以从第i-1个台阶爬1个台阶到达,也可以从第i-2个台阶爬2个台阶到达。因此,
dp[i] = dp[i-1] + dp[i-2]。 - 循环计算
dp[i],直到计算到第n个台阶的方法数。 - 返回
dp[n],即爬到第n个台阶的方法数。