一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vhMGVVKn-1607527207480)( https://assets.leetcode.com/uploads/2018/10/22/robot_maze.png)]
示例 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
提示:
1 <= m, n <= 100
题目数据保证答案小于等于 2 * 109
分析
从起点到终点,有很多条路径,那么怎样才能找到所有路径呢?
首先我们可以用最笨的方法,即将每种可能都尝试一遍,利用回溯+保存状态信息,但是这样做实在是太麻烦了,而且说不定很慢,那么该怎样做呢?
由于限制了只能右行或者下行,不存在先左再右回到原地这种毫无意义的操作,通过分析我们可以看到这个路径具有两个特点:
- 起点到同一行或同一列的任意点都只能有一条路径
- 想要到达某一点Point(x,y),x>1&&y>1,只能通过点Point(x-1,y)或Point(x,y-1)
从第二点可以看出,到达某一点的路线条数等于到达它上面的点和到达它左边的点路线条数之和
即公式
num[x,y] = num[x-1,y] + num[x,y-1]
再加上x==1和y==1的情况都只有一条路线,我们已经可以利用动态规划的思想来完成这个任务了!
/*
执行结果:通过
执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗:6.3 MB, 在所有 C++ 提交中击败了62.24%的用户
*/
int dp[101][101];
int uniquePaths(int m, int n) {
if (1 == m && 1 == n) {//如果终点子在同行或同列
return 1;
}
for (int i = 0; i < m; ++i) {
dp[0][i] = 1;
}
for (int i = 1; i < n; ++i) {
dp[i][0] = 1;
for (int j = 1; j < m; ++j) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cout << dp[i][j] << '\t';
} cout << endl;
}
return dp[n - 1][m - 1];
}