题目
一个机器人位于一个 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
提示:
1 <= m, n <= 100
-
解题方法
动态规划(二维动态数组)
构建二维动态数组
dp[x][y]
表示到达位置(x, y)
的路线总数,则有如下递推关系:
时间复杂度O(mn)
,空间复杂度O(mn)
。
C++代码:class Solution {
public:
int uniquePaths(int m, int n) {
int board[m][n];
board[0][0] = 1;
for(int i=1; i<m*n; i++) {
int x = i / n;
int y = i % n;
if(x==0) board[x][y] = board[x][y-1];
else if(y==0) board[x][y] = board[x-1][y];
else board[x][y] = board[x][y-1] + board[x-1][y];
}
return board[m-1][n-1];
}
};
动态规划(一维数组优化)
由于本题中只能向右或向下移动,导致第一行和第一列都为
1
,因此可以仅采用一维数组进行递推,选取较小边构建一维数组,假设m <= n
,则递推关系如下:dp
数组的初始值为1
。
时间复杂度O(mn)
,空间复杂度O(min(m, n))
C++代码:class Solution {
public:
int uniquePaths(int m, int n) {
if(m>n) return uniquePaths(n, m);
int board[m];
for(int i=0; i<m; i++) board[i] = 1;
for(int i=1; i<n; i++) {
for(int j=1; j<m; j++) {
board[j] += board[j-1];
}
}
return board[m-1];
}
};
组合数学
从左上角移动到右下角,一次向右或向下移动一格,则一共需要
m+n-2
次移动,其中m-1
次为向下移动,故答案为
时间复杂度O(min(m, n))
,空间复杂度O(1)
C++代码:class Solution {
public:
int uniquePaths(int m, int n) {
if(m>n) return uniquePaths(n, m);
long long result = 1;
for(int i=n, j=1; j<m; i++, j++) result = result * i / j;
return result;
}
};