一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:

Input: m = 3, n = 7Output: 28
示例 2:
Input: m = 3, n = 2Output: 3Explanation:From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:1. Right -> Down -> Down2. Down -> Down -> Right3. Down -> Right -> Down
示例 3:
Input: m = 7, n = 3Output: 28
示例 4:
Input: m = 3, n = 3Output: 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 conditonif( row == metadata[0] - 1 && col == metadata[1] - 1 ) {metadata[2]++;return;}// 2. Walk every node that not visitedvisited[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];}};
