一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-paths-ii
思路
这道题有一道题目大意相同,但是比这道题简单一些的题。可以先做会不同路径,再来做不同路径ii。
我们会想到动态规划,因为这道题得到的答案,与前面做的决定有关。
使用1来标记障碍物,0标记可以通过。
由于1来标记障碍物,如果我们的路径就有一条,这样就会产生歧义,所以我们首先将1改为-1,表示障碍物。
再初始化第一行和第一列。由于第一行只能从左边到,所以只要没有障碍物,就是1,
同理,第一列只能从上到下,所以第一列只要是没有障碍物就是1。
如果初始化的第一行第一列有障碍物,我们就标记为1<<31 - 1,也就是不可到达。
初始化行和列之后,我们计算中间的数值。
中间的数值根据左侧和上侧的值决定,如果上侧或者左侧的值为-1或者1<<31-1则舍弃掉,直接取能到达的一侧的值,如果两个都不能到达,我们设置该值为1<<31-1也是不可到达。
最后如果右下角的数值是-1或者1<<31-1,则我们返回0,也就是0条路径。
/*
* @lc app=leetcode.cn id=63 lang=golang
*
* [63] 不同路径 II
*/
// @lc code=start
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
if obstacleGrid[len(obstacleGrid)-1][len(obstacleGrid[0])-1] == 1 {
return 0
}
if obstacleGrid[0][0] == 1 {
return 0
}
update(obstacleGrid)
//初始化纵列
for i := 1; i < len(obstacleGrid); i++ {
if obstacleGrid[i-1][0] == -1 || obstacleGrid[i-1][0] == 1<<31-1 {
obstacleGrid[i][0] = 1<<31 - 1
continue
}
if obstacleGrid[i][0] == -1 {
continue
}
obstacleGrid[i][0] = 1
}
//初始化横行
for i := 1; i < len(obstacleGrid[0]); i++ {
if obstacleGrid[0][i-1] == -1 || obstacleGrid[0][i-1] == 1<<31-1 {
obstacleGrid[0][i] = 1<<31 - 1
continue
}
if obstacleGrid[0][i] == -1 {
continue
}
obstacleGrid[0][i] = 1
}
//计算中间值
for i := 1; i < len(obstacleGrid); i++ {
for k := 1; k < len(obstacleGrid[i]); k++ {
if obstacleGrid[i][k] == -1 {
continue
}
if obstacleGrid[i-1][k] == -1 && obstacleGrid[i][k-1] == -1 {
obstacleGrid[i][k] = 1<<31 - 1
continue
}
if obstacleGrid[i-1][k] == 1<<31-1 && obstacleGrid[i][k-1] == 1<<31-1 {
obstacleGrid[i][k] = 1<<31 - 1
continue
}
if obstacleGrid[i-1][k] == -1 || obstacleGrid[i-1][k] == 1<<31-1 {
obstacleGrid[i][k] = obstacleGrid[i][k-1]
continue
}
if obstacleGrid[i][k-1] == -1 || obstacleGrid[i][k-1] == 1<<31-1 {
obstacleGrid[i][k] = obstacleGrid[i-1][k]
continue
}
obstacleGrid[i][k] = obstacleGrid[i-1][k] + obstacleGrid[i][k-1]
}
}
obstacleGrid[0][0] = 1
if obstacleGrid[len(obstacleGrid)-1][len(obstacleGrid[0])-1] == 1<<31-1 {
return 0
} else {
return obstacleGrid[len(obstacleGrid)-1][len(obstacleGrid[0])-1]
}
}
func min(m, n int) int {
if m < n {
return m
} else {
return n
}
}
func update(nums [][]int) {
for i := 0; i < len(nums); i++ {
for k := 0; k < len(nums[0]); k++ {
if nums[i][k] == 1 {
nums[i][k] = -1
}
}
}
}
// @lc code=end