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

本文介绍了一种使用动态规划解决带障碍物的网格路径计数问题的方法。在一个mxn的网格中,机器人从左上角出发,只能向下或向右移动,并避开障碍物,到达右下角。文章详细阐述了如何通过构建dp数组来高效地计算所有可能的路径数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个机器人位于一个 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 }

 

转载于:https://www.cnblogs.com/zzw1024/p/10663293.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值