题目

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

示例 1:
image.png

  1. 输入:m = 3, n = 7
  2. 输出:28

示例 2:

  1. 输入:m = 3, n = 2
  2. 输出:3
  3. 解释:
  4. 从左上角开始,总共有 3 条路径可以到达右下角。
  5. 1. 向右 -> 向下 -> 向下
  6. 2. 向下 -> 向下 -> 向右
  7. 3. 向下 -> 向右 -> 向下

示例 3:

  1. 输入:m = 7, n = 3
  2. 输出:28

示例 4:

  1. 输入:m = 3, n = 3
  2. 输出:6

提示:

  • 1 <= m, n <= 100
  • 题目数据保证答案小于等于 2 * 10^9

    解题方法

    动态规划(二维动态数组)

    构建二维动态数组dp[x][y]表示到达位置(x, y)的路线总数,则有如下递推关系:
    62. 不同路径 - 图2
    时间复杂度O(mn),空间复杂度O(mn)
    C++代码:

    1. class Solution {
    2. public:
    3. int uniquePaths(int m, int n) {
    4. int board[m][n];
    5. board[0][0] = 1;
    6. for(int i=1; i<m*n; i++) {
    7. int x = i / n;
    8. int y = i % n;
    9. if(x==0) board[x][y] = board[x][y-1];
    10. else if(y==0) board[x][y] = board[x-1][y];
    11. else board[x][y] = board[x][y-1] + board[x-1][y];
    12. }
    13. return board[m-1][n-1];
    14. }
    15. };

    动态规划(一维数组优化)

    由于本题中只能向右或向下移动,导致第一行和第一列都为1,因此可以仅采用一维数组进行递推,选取较小边构建一维数组,假设m <= n,则递推关系如下:
    62. 不同路径 - 图3
    dp数组的初始值为1
    时间复杂度O(mn),空间复杂度O(min(m, n))
    C++代码:

    1. class Solution {
    2. public:
    3. int uniquePaths(int m, int n) {
    4. if(m>n) return uniquePaths(n, m);
    5. int board[m];
    6. for(int i=0; i<m; i++) board[i] = 1;
    7. for(int i=1; i<n; i++) {
    8. for(int j=1; j<m; j++) {
    9. board[j] += board[j-1];
    10. }
    11. }
    12. return board[m-1];
    13. }
    14. };

    组合数学

    从左上角移动到右下角,一次向右或向下移动一格,则一共需要m+n-2次移动,其中m-1次为向下移动,故答案为
    62. 不同路径 - 图4
    时间复杂度O(min(m, n)),空间复杂度O(1)
    C++代码:

    1. class Solution {
    2. public:
    3. int uniquePaths(int m, int n) {
    4. if(m>n) return uniquePaths(n, m);
    5. long long result = 1;
    6. for(int i=n, j=1; j<m; i++, j++) result = result * i / j;
    7. return result;
    8. }
    9. };