一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
Input: m = 3, n = 7
Output: 28
示例 2:
Input: m = 3, n = 2
Output: 3
Explanation:
From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:
1. Right -> Down -> Down
2. Down -> Down -> Right
3. Down -> Right -> Down
示例 3:
Input: m = 7, n = 3
Output: 28
示例 4:
Input: m = 3, n = 3
Output: 6
提示:
- 1 ≤
m
,n
≤ 100 - 题目数据保证答案小于等于 2 × 10
思路
最开始尝试用DFS,但在大的测试数据下超时了。后来想想可以用动态规划。
我们创建一个二维dp[][]
数组,里面的值含义是:有多少个方法来到当前坐标位置。
当只有 1 行 1 列时,
dp[0][0] = 1
;假设有 3 行 7 列时,
dp[][]
数组的第0行和第0列的值全是1,因为机器人每次只能往右走或往下走:dp[3][7] = {
1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0
}
- 当走到 row 行 col 列时,它可能是从 上面 来的或从 左边 来的,所以到当前位置的走法有: (col)%20%3D%20%0A%5Cbegin%7Bcases%7D%0A1%2C%20%26row%20%3D%200%2C%20col%20%3D%200%5C%5C%0Adp(row-1)(col)%20%2B%20dp(row)(col-1)%2C%20%26%20row%20%5Cge%201%2C%20col%20%5Cge%201%0A%5Cend%7Bcases%7D%0A#card=math&code=dp%28row%29%28col%29%20%3D%20%0A%5Cbegin%7Bcases%7D%0A1%2C%20%26row%20%3D%200%2C%20col%20%3D%200%5C%5C%0Adp%28row-1%29%28col%29%20%2B%20dp%28row%29%28col-1%29%2C%20%26%20row%20%5Cge%201%2C%20col%20%5Cge%201%0A%5Cend%7Bcases%7D%0A)
有了状态转移方程,我们能求出各阶段dp[][]
的值。结果返回dp[][]
数组右下角的那个元素。
代码
// 第一次尝试:37/62 超出时间限制
class Solution {
public:
int uniquePaths(int m, int n) {
if( m == 0 || n == 0 ) return 0;
if( n == 1 ) return 1;
bool visited[ m ][101];
for(int i = 0; i < m; i++) {
for(int j = 0; j < 101; j++) {
visited[i][j] = false;
}
}
int metadata[3] = { m, n, 0 };
dfs(0, 0, visited, metadata);
return metadata[2];
}
void dfs(int row, int col, bool visited[][101], int metadata[]) {
// 1. Exit conditon
if( row == metadata[0] - 1 && col == metadata[1] - 1 ) {
metadata[2]++;
return;
}
// 2. Walk every node that not visited
visited[row][col] = true;
if( row+1 < metadata[0] && !visited[row+1][col] ) dfs(row + 1, col, visited, metadata);
if( col+1 < metadata[1] && !visited[row][col+1] ) dfs(row, col + 1, visited, metadata);
visited[row][col] = false;
}
};
AC代码如下:
class Solution {
public:
int uniquePaths(int m, int n) {
if( m == 0 || n == 0 ) return 0;
if( n == 1 ) return 1;
int dp[m][n];
for(int i = 0; i < n; i++) dp[0][i] = 1;
for(int i = 0; i < m; i++) dp[i][0] = 1;
for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};