1 题目
题目:不同的路径(Unique Paths)
描述:有一个机器人位于一个 m × n 个网格左上角。机器人每一时刻只能向下或者向右移动一步。机器人试图达到网格的右下角。问有多少条不同的路径?
lintcode题号——114,难度——easy
样例1:
输入:
n = 1
m = 3
输出:1
解释:只有一条通往目标位置的路径。
样例2:
输入:
n = 3
m = 3
输出:6
解释:
D : Down;R : Right
DDRR
DRDR
DRRD
RRDD
RDRD
RDDR
一共六种走法。
2 解决方案
2.1 思路
需要求出具体方案的个数,且直接使用遍历法会对节点产生重复计算的问题,考虑使用动态规划,将状态定义为表示走到位置(i,j)的路径数量,则到达位置(i,j)的路径数=到达位置(i,j-1)的路径数+到达位置(i-1,j)的路径数,理清动态规划的四要素即可解出。
2.2 时间复杂度
每个节点都需要计算一次,若节点数为n,则时间复杂度为O(n)。
2.3 空间复杂度
使用了容量为n的二维数组来承载运算,所以空间复杂度为O(n)。
3 源码
细节:
- 动态规划的四要素:状态、方程、初始化、答案。(四要素在之前的题目数字三角形1中有详细介绍)
- 状态:用
dp[i][j]
表示走到位置(i,j)的路径数量。 - 方程:
dp[i][j] = dp[i][j - 1] + dp[i - 1][j]
,到达位置(i,j)的路径数=到达位置(i,j-1)的路径数+到达位置(i-1,j)的路径数。 - 初始化:网格的上边缘和左边缘上的所有节点都只有一种方式能到达。
- 答案:到达右下角的路径数,即
dp[maxRow][maxCol]
。
C++版本:
/**
* @param m: positive integer (1 <= m <= 100)
* @param n: positive integer (1 <= n <= 100)
* @return: An integer
*/
int uniquePaths(int m, int n) {
// write your code here
if (m <= 0 || n <= 0)
{
return 0;
}
// 状态:dp[i][j]表示走到位置(i,j)的路径数量
vector<vector<int>> dp(m, vector<int>(n));
// 初始化:网格的上边缘和左边缘
for (int i = 1; i < dp.size(); i++)
{
dp[i][0] = 1;
}
for (int j = 1; j < dp.front().size(); j++)
{
dp[0][j] = 1;
}
for (int i = 1; i < dp.size(); i++)
{
for (int j = 1; j < dp.front().size(); j++)
{
// 方程:到达位置(i,j)的路径数=到达位置(i,j-1)的路径数+到达位置(i-1,j)的路径数
dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
}
}
return dp[dp.size() - 1][dp.front().size() - 1]; // 答案:到达右下角的路径数
}
数字三角形:https://blog.csdn.net/SeeDoubleU/article/details/124678103 ↩︎