力扣算法题—063不同路径2

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

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

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 1 和 0 来表示。

说明:m 和 的值均不超过 100。

示例 1:

输入:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
输出: 2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右

 1 #include "_000库函数.h"
 2 
 3 
 4 //还是用动态规划Dynamic Programming来解,我们使用一个二维的dp数组,大小为(m + 1) x(n + 1),
 5 //这里的dp[i][j] 表示到达(i - 1, j - 1) 位置的不同路径的数量,
 6 //那么i和j需要更新的范围就是[1, m] 和[1, n]。状态转移方程跟之前那道题是一样的,
 7 //因为每个位置只能由其上面和左面的位置移动而来,
 8 //所以也是由其上面和左边的dp值相加来更新当前的dp值,即:
 9 //
10 //dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
11 //
12 //这里就能看出来我们初始化dp数组的大小为(m + 1) x(n + 1),
13 //是为了handle边缘情况,当i或j为0时,减1可能会出错。
14 //当某个位置是障碍物时,其dp值为0,我们直接跳过该位置即可。
15 //我们还需要初始化dp数组的某个值,使得其能正常累加。当起点不是障碍物时,
16 //其dp值应该为值,即dp[1][1] = 1,由于其是由 dp[0][1] + dp[1][0] 更新而来,
17 //所以二者中任意一个初始化为1即可。由于之后LeetCode更新了这道题的test case,
18 //使得使用int型的dp数组会有溢出的错误,所以我们改为使用long型的数组来避免overflow,代码如下:
19 
20 class Solution {
21 public:
22     int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
23         if (obstacleGrid.empty() || obstacleGrid[0].empty() || obstacleGrid[0][0] == 1) return 0;
24         int m = obstacleGrid.size(), n = obstacleGrid[0].size();
25         vector<vector<long>> dp(m + 1, vector<long>(n + 1, 0));
26         dp[0][1] = 1;
27         for (int i = 1; i <= m; ++i) {
28             for (int j = 1; j <= n; ++j) {
29                 if (obstacleGrid[i - 1][j - 1] != 0) continue;
30                 dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
31             }
32         }
33         return dp[m][n];
34     }
35 };
36 
37 void T063() {
38     Solution s;
39     vector<vector<int>>v;
40     v = { {0, 0, 0},
41           {0, 1, 0},
42           {0, 0, 0} };
43     cout << s.uniquePathsWithObstacles(v) << endl;
44 }

猜你喜欢

转载自www.cnblogs.com/zzw1024/p/10663293.html