1.题目描述
不同路径
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7
输出:28
示例 2:
输入:m = 3, n = 2
输出:3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右
3. 向下 -> 向右 -> 向下
示例 3:
输入:m = 7, n = 3
输出:28
示例 4:
输入:m = 3, n = 3
输出:6
2.思路
2.1 代码
这是一道入门级的动态规划题,首先考虑使用递归来进行解答。使用递归时,有以下四种情况需要进行考虑
- 当机器人走到最右下角时,表示已经完成,此时应当返回1;
- 当机器人走到最下方时,此时只能往右边走;
- 当机器人走到最右方时,此时只能往下方走;
- 其他情况往右往下走均可;
针对以上四种情况使用二维数组进行模拟,代码如下:
class Solution {
public int uniquePaths(int m, int n) {
int[][] arr = new int[m][n];
return process(arr, 0, 0);
}
public int process(int[][] arr, int right, int down) {
if (down == arr.length - 1 && right == arr[0].length - 1) {
return 1;
} else if (down == arr.length - 1) {
return process(arr, right + 1, down);
} else if (right == arr[0].length - 1) {
return process(arr, right, down + 1);
} else {
int p1 = process(arr, right + 1, down);
int p2 = process(arr, right, down + 1);
return p1 + p2;
}
}
}
题目给出示例均正确,但是当数字大时,会超出时间限制,因此进行动态规划改造。改造同样使用一个二维数组,并且最后一行和最后一列均为1,中间部分为下方与右方单元格之和,得到以下代码:
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
dp[m - 1][n - 1] = 1;
for (int i = m - 2; i >= 0; i--) {
dp[i][n - 1] = dp[i + 1][n - 1];
}
for (int i = n - 2; i >= 0; i--) {
dp[m - 1][i] = dp[m - 1][i + 1];
}
for (int raw = m - 2; raw >= 0; raw--) {
for (int col = n - 2; col >= 0; col--) {
int p1 = dp[raw][col + 1];
int p2 = dp[raw + 1][col];
dp[raw][col] = p1 +p2;
}
}
return dp[0][0];
}
}
2.2 测试结果
通过测试
3.总结
- 使用递归方式进行解答时需要考虑边界条件,即最下方行、最右边列及右下角单元格
- 使用递归时会造成超出时间限制,因此使用动态规划改造