leetcode:62. 不同路径 - 力扣(LeetCode)
题目
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
- 输入:m = 3, n = 7
- 输出:28
示例 2:
- 输入:m = 2, n = 3
- 输出:3
解释: 从左上角开始,总共有 3 条路径可以到达右下角。
- 向右 -> 向右 -> 向下
- 向右 -> 向下 -> 向右
- 向下 -> 向右 -> 向右
示例 3:
- 输入:m = 7, n = 3
- 输出:28
示例 4:
- 输入:m = 3, n = 3
- 输出:6
提示:
- 1 <= m, n <= 100
- 题目数据保证答案小于等于 2 * 10^9
思路
动规五部曲
(1)dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。
(2)dp[i][j]只能从dp[i-1][j]和dp[i][j-1]获取,所以dp[i][j] = dp[i - 1][j] + dp[i][j - 1],这里的逻辑有点像前几天做的爬楼梯那个题,只能从上一个或者上上个楼梯爬过来。
(3)dp数组的第一行和第一列一定都是1,因为只能是一直向右走或者向下走,所以初始化
for (int i = 0; i < m; i++) dp[i][0] = 1;
for (int j = 0; j < n; j++) dp[0][j] = 1;
(4)每个网格的取值要看它的左边和它的上边,所以i遍历每一行,j遍历每一列,用两层for循环遍历就行了,不过起始位置是i=1和j=1。
(5)举例推导
代码如下:
#include <iostream>
#include <vector>
using namespace std;
class Solution
{
public:
// 计算一个m行n列的网格中的唯一路径数
// 使用动态规划的方法解决问题
int uniquePaths(int m, int n)
{
// 初始化一个m行n列的二维数组dp,用于存储到达每个位置的路径数
vector<vector<int>> dp(m, vector<int>(n));
// 初始化第一列的路径数,由于只能向下移动,所以只有一条路径
for (int i = 0; i < m; i++)
{
dp[i][0] = 1;
}
// 初始化第一行的路径数,由于只能向右移动,所以只有一条路径
for (int j = 0; j < n; j++)
{
dp[0][j] = 1;
}
// 从第二行第二列开始,填充dp数组
// 每个位置的路径数是其上方和左方位置路径数的和
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];
}
};
总结
有点像小学里面的一些画图题,递归公式不难想。