A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

Note: m and n will be at most 100.

Example 1:

Input:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
Output: 2
Explanation:
There is one obstacle in the middle of the 3x3 grid above.
There are two ways to reach the bottom-right corner:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right

这道题是之前那道 Unique Paths 的延伸,在路径中加了一些障碍物,还是用动态规划 Dynamic Programming 来解,使用一个二维的 dp 数组,大小为 (m+1) x (n+1),这里的 dp[i][j] 表示到达 (i-1, j-1) 位置的不同路径的数量,那么i和j需要更新的范围就是 [1, m] 和 [1, n]。状态转移方程跟之前那道题是一样的,因为每个位置只能由其上面和左面的位置移动而来,所以也是由其上面和左边的 dp 值相加来更新当前的 dp 值,如下所示:

dp[i][j] = dp[i-1][j] + dp[i][j-1]

这里就能看出来初始化 d p数组的大小为 (m+1) x (n+1),是为了 handle 边缘情况,当i或j为0时,减1可能会出错。当某个位置是障碍物时,其 dp 值为0,直接跳过该位置即可。这里还需要初始化 dp 数组的某个值,使得其能正常累加。当起点不是障碍物时,其 dp 值应该为1,即dp[1][1] = 1,由于其是由 dp[0][1] + dp[1][0] 更新而来,所以二者中任意一个初始化为1即可。由于之后 LeetCode 更新了这道题的 test case,使得使用 int 型的 dp 数组会有溢出的错误,所以改为使用 long 型的数组来避免 overflow,代码如下:

解法一:

class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if (obstacleGrid.empty() || obstacleGrid[].empty() || obstacleGrid[][] == ) return ;
int m = obstacleGrid.size(), n = obstacleGrid[].size();
vector<vector<long>> dp(m + , vector<long>(n + , ));
dp[][] = ;
for (int i = ; i <= m; ++i) {
for (int j = ; j <= n; ++j) {
if (obstacleGrid[i - ][j - ] != ) continue;
dp[i][j] = dp[i - ][j] + dp[i][j - ];
}
}
return dp[m][n];
}
};

或者我们也可以使用一维 dp 数组来解,省一些空间,参见代码如下:

解法二:

class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if (obstacleGrid.empty() || obstacleGrid[].empty() || obstacleGrid[][] == ) return ;
int m = obstacleGrid.size(), n = obstacleGrid[].size();
vector<long> dp(n, );
dp[] = ;
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (obstacleGrid[i][j] == ) dp[j] = ;
else if (j > ) dp[j] += dp[j - ];
}
}
return dp[n - ];
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/63

类似题目:

Unique Paths

Unique Paths III

参考资料:

https://leetcode.com/problems/unique-paths-ii/

https://leetcode.com/problems/unique-paths-ii/discuss/23250/Short-JAVA-solution

https://leetcode.com/problems/unique-paths-ii/discuss/23248/My-C%2B%2B-Dp-solution-very-simple!

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Unique Paths II 不同的路径之二的更多相关文章

  1. [LeetCode] 63. Unique Paths II 不同的路径之二

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...

  2. LEETCODE —— Unique Paths II [动态规划 Dynamic Programming]

    唯一路径问题II Unique Paths II Follow up for "Unique Paths": Now consider if some obstacles are ...

  3. LeetCode: Unique Paths II 解题报告

    Unique Paths II Total Accepted: 31019 Total Submissions: 110866My Submissions Question Solution  Fol ...

  4. LEETCODE —— Unique Paths II [Dynamic Programming]

    唯一路径问题II Unique Paths II Follow up for "Unique Paths": Now consider if some obstacles are ...

  5. LeetCode OJ:Unique Paths II(唯一路径II)

    Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...

  6. [Leetcode] unique paths ii 独特路径

    Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...

  7. [leetcode]Unique Paths II @ Python

    原题地址:https://oj.leetcode.com/problems/unique-paths-ii/ 题意: Follow up for "Unique Paths": N ...

  8. Leetcode Unique Paths II

    Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...

  9. Leetcode之动态规划(DP)专题-63. 不同路径 II(Unique Paths II)

    Leetcode之动态规划(DP)专题-63. 不同路径 II(Unique Paths II) 初级题目:Leetcode之动态规划(DP)专题-62. 不同路径(Unique Paths) 一个机 ...

随机推荐

  1. C# - 多线程 之 异步编程

    异步编程 同步编程,请求响应模型,同步化.顺序化.事务化. 异步编程,事件驱动模型,以 Fire and Forget 方式实现. 异步编程模式  -§- 异步编程模型 (APM) 模式: IAsyn ...

  2. Hibernnate延迟加载策略(这么详细你还看不懂)

    好久没有认真写过博客了,今天就好好的写一篇吧!!!!!!!!! 当Hibernate 从数据库中加载某个对象(例如:Dept对象)时,如果同时自动加载所有的关联的某个对象(例如:Emp对象),而程序实 ...

  3. Web Worker javascript多线程编程(一)

    什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...

  4. [deviceone开发]-do_Album的简单示例

    一.简介do_Album用来打开手机系统提供的相册,能选择一张或多张图片返回给开发者,通常相册的图片比较大,要经过缩放.有的时候用户也需要把别的地方获取到到图片收藏到系统相册.这个示例简单展示这个组件 ...

  5. 深入理解javascript选择器API系列第三篇——h5新增的3种selector方法

    × 目录 [1]方法 [2]非实时 [3]缺陷 前面的话 尽管DOM作为API已经非常完善了,但是为了实现更多的功能,DOM仍然进行了扩展,其中一个重要的扩展就是对选择器API的扩展.人们对jQuer ...

  6. JavaScript 常用代码

    未知对象 对象类型名称:xobject.constructor.name 对象成员键名:Object.keys(xobject) 枚举对象成员及其值:for(var propertyName in r ...

  7. Android--Volley框架的使用

    一.Volley特点 通信更快,更简单(数据量不大,但网络通信频繁) Get.Post网络请求及网络图像的高效率异步处理 排序(可以通过网络请求的优先级进行处理) 网络请求的缓存 多级别取消请求 和A ...

  8. Genymotion报Unable to load virtualbox engine错误

  9. 基于JQuery实现的文本框自动填充功能

    1. 实现的方法 /* * js实现的文本框的自动完成功能 */ function doAutoComplete(textid,dataid,url){ $("#" + texti ...

  10. 3、项目资源的提供 - PMO项目管理办公室

    PMO项目管理办公室也需要对项目相关的资源进行提供,从而针对项目的资源也进行标准化和规范化的管理.也就是说,PMO项目管理办公室就是提供项目相关的规范化资源内容,从而统一管理项目相关的内容,达到规范的 ...