62.一个机器人位于一个 m x n 网格的左上角 。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。
问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7
输出:28
示例 2:
输入:m = 3, n = 2
输出:3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右
3. 向下 -> 向右 -> 向下
- 做不出来,只有超时解法:直接递归,从终点 (m,n) 到起点 (1,1) 和最终结果一样。
-
public int uniquePaths(int m, int n) { // 走到起点说明当前路径可行 if(m == 1 && n == 1){ return 1; } // 走得超出边界了说明路径不可行 if(m < 1 || n < 1){ return 0; } // 递归往右一步或者往下一步是否可行 return uniquePaths(m-1,n) + uniquePaths(m,n-1); }
- 题号:62
- 他人解法:首先定义 f[i][j] 为到达位置 (i,j) 的不同路径数量。从终点 f[m-1][n-1] 来看,由于只能往下或者往右走,所以到达终点前的位置只有两种可能,也就是他的左边或者上面,即 f[m-2][n-1] 和 f[m-1][n-2],继续推断,那么可以得到 f[i][j] = f[i-1][j] + f[i][j-1],但是有个问题,如果你已经贴着上墙了,你还可能是从上面和左边过来的吗,很明显不是,这时你只有可能是从左边来到这个点,也就是此时 f[i][j] = f[i-1][j],同理如果已经贴着左墙了,肯定是从上面来的。
-
public int uniquePaths(int m, int n) { int[][] f = new int[m][n]; f[0][0] = 1; // i 表示行,所以表示上下移动,j 表示列,所以表示左右移动 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i > 0 && j > 0) { f[i][j] = f[i - 1][j] + f[i][j - 1]; } else if (i > 0) { // 此时说明 j==0,也就是在第 0 行列,等于贴着左墙了 // 只能往下移动,说明他和上一个位置相同 f[i][j] = f[i - 1][j]; } else if (j > 0) { // 此时说明 i==0,和 j==0 同理 f[i][j] = f[i][j - 1]; } } } return f[m - 1][n - 1]; }
- 也可以修改一下,增加一行和一列,然后起点就改为 (0,1) 或 (1,0),这时那种从墙壁外过来的下标,值都是 0,就不需要考虑贴墙的情况了
-
public int uniquePaths(int m, int n) { int[][] f = new int[m+1][n+1]; f[1][0] = 1; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { f[i][j] = f[i - 1][j] + f[i][j - 1]; } } return f[m][n]; }
- 参考链接