[LeetCode] 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 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 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 不同的路径之二的更多相关文章
- [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 ...
- LEETCODE —— Unique Paths II [动态规划 Dynamic Programming]
唯一路径问题II Unique Paths II Follow up for "Unique Paths": Now consider if some obstacles are ...
- LeetCode: Unique Paths II 解题报告
Unique Paths II Total Accepted: 31019 Total Submissions: 110866My Submissions Question Solution Fol ...
- LEETCODE —— Unique Paths II [Dynamic Programming]
唯一路径问题II Unique Paths II Follow up for "Unique Paths": Now consider if some obstacles are ...
- LeetCode OJ:Unique Paths II(唯一路径II)
Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...
- [Leetcode] unique paths ii 独特路径
Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...
- [leetcode]Unique Paths II @ Python
原题地址:https://oj.leetcode.com/problems/unique-paths-ii/ 题意: Follow up for "Unique Paths": N ...
- Leetcode Unique Paths II
Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...
- Leetcode之动态规划(DP)专题-63. 不同路径 II(Unique Paths II)
Leetcode之动态规划(DP)专题-63. 不同路径 II(Unique Paths II) 初级题目:Leetcode之动态规划(DP)专题-62. 不同路径(Unique Paths) 一个机 ...
随机推荐
- Android指纹识别深入浅出分析到实战(6.0以下系统适配方案)
指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...
- Linux资源管理-IO优先级
前一篇博客介绍了利用 cgroup 来控制进程的 CPU和内存使用情况, 这次补上使用 cgroup 来控制进程的IO优先级的方法. 前提条件 如果想控制进程的IO优先级, 需要内核的支持, 内核编译 ...
- 求解第N个素数
任务 求解第 10,0000.100,0000.1000,0000 ... 个素数(要求精确解). 想法 Sieve of Eratosthenes 学习初等数论的时候曾经学过埃拉托斯特尼筛法(Sie ...
- 常用JavaScript触发事件
事件句柄 onclick=JavaScript:鼠标单击某个对象.3 ondblclick=JavaScript:鼠标双击某个对象.3 onmousedown=JavaScript:某个鼠标键被按下. ...
- C# Linq排序
今天在家看了一下linq,实践了一下书中代码,发现排序和查重的先后顺序太重要了. using System; using System.Collections.Generic; using Syste ...
- Java下载文件(流的形式)
@RequestMapping("download") @ResponseBody public void download(HttpServletResponse respons ...
- 用大白话聊聊JavaSE -- 如何理解Java Bean(一)
首先,在开始本章之前,先说一个总的概念:所谓的Java Bean,就是一个java类,编译后成为了一个后缀名是 .class的文件.这就是Java Bean,很多初学者,包括当年的我自己,总是被这些专 ...
- python爬虫成长之路(一):抓取证券之星的股票数据
获取数据是数据分析中必不可少的一部分,而网络爬虫是是获取数据的一个重要渠道之一.鉴于此,我拾起了Python这把利器,开启了网络爬虫之路. 本篇使用的版本为python3.5,意在抓取证券之星上当天所 ...
- 物联网框架SuperIO 2.2.9和ServerSuperIO 2.1同时更新,更适用于类似西门子s7-200发送多次数据,才能读取数据的情况
一.解决方案 二.更新内容 1.修改IRunDevice接口,把void Send(io,bytes)改成int Send(io,bytes).2.修改网络控制器,发送数据不直接使用IO实例,改为使用 ...
- 4.6 .net core依赖注入的封装
现在流行的系统一般都采用依赖注入的实现方式,利用DI容器来直接获取所用到的类/接口的实例..net core也一样采用DI的方式,提供了DI容器的接口IServiceCollection,并提供了基于 ...