一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start”
)。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为
“Finish” )。
问总共有多少条不同的路径?
示例:
输入:m = 3, n = 7 输出:28
输入:m = 3, n = 2 输出:3 解释: 从左上角开始,总共有 3
条路径可以到达右下角。 1. 向右 -> 向下 -> 向下 2. 向下 -> 向下
-> 向右 3. 向下 -> 向右 -> 向下
思路:
方法一:备忘录
我们知道最右下角一定是由它的左边或者上边来的。
所以状态转移方程为:
1
| dp[x][y] = dp[x - 1][y] + dp[x][y - 1];
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public: vector<vector<int> > memo; int uniquePaths(int m, int n) { memo.resize(m, vector<int>(n, 0)); return dp(m - 1, n - 1); } int dp(int x, int y){ if(x == 0 && y == 0) return 1; if(x < 0 || y < 0) return 0;
if(memo[x][y] != 0) return memo[x][y];
memo[x][y] = dp(x - 1, y) + dp(x, y - 1); return memo[x][y]; } };
|
方法二:迭代
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
class Solution1 { public: int uniquePaths(int m, int n) { vector<vector<int> > dp(m, vector<int>(n , 0)); for(int i = 0; i < m; i++){ dp[i][0] = 1; } for(int i = 0; i < n; i++){ dp[0][i] = 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]; } };
|
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start”
)。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为
“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
示例:
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]] 输出:2 解释:3x3
网格的正中间有一个障碍物。 从左上角到右下角一共有 2 条不同的路径: 1.
向右 -> 向右 -> 向下 -> 向下 2. 向下 -> 向下 -> 向右
-> 向右
思路:
和上一题的思路一样,只是我们在处理第0行或者第0列时,如果碰到障碍物需要退出,并且在其他位置时需要跳过障碍物,即:
1 2 3 4 5 6 7
| for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { if(obstacleGrid[i][j] != 1) { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Solution { public: int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int m = obstacleGrid.size(), n = obstacleGrid[0].size(); vector<vector<int>> dp(m, vector<int>(n, 0)); for(int i = 0; i < m; i++) { if(obstacleGrid[i][0] == 1) break; dp[i][0] = 1; } for(int i = 0; i < n; i++) { if(obstacleGrid[0][i] == 1) break; dp[0][i] = 1; } for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { if(obstacleGrid[i][j] != 1) { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } } return dp[m - 1][n - 1]; } };
|