一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 1 和 0 来表示。
说明:m和n的值不超过100。
示例1:
输入: [ [0,0,0], [0,1,0], [0,0,0] ] 输出: 2 解释: 3x3 网格的正中间有一个障碍物。 从左上角到右下角一共有 2 条不同的路径: 1. 向右 -> 向右 -> 向下 -> 向下 2. 向下 -> 向下 -> 向右 -> 向右
解法一: 动态规划
思想算法:
- 如果第一个格子点是obstacleGrid[0][0] 是 1, 说明有障碍物,那么机器人就不能做任何的移动,我们就直接返回0;
- 否则如果obstacleGrid[0][0] 是 0, 我们初始化这个值为1,然后继续算法;
- 遍历第一行,如果有个格子是为1,说明当前节点有障碍物,没有路径可走,设置为0;否则设这个值是前一个节点的值,如下:
let verticalValue = (obstacleGrid[0][i] == 0 && dp[0][i - 1] == 1) ? 1 : 0
dp[0].append(verticalValue)
- 遍历第一列,如果有一个格子初始值是1, 说明当前节点为障碍物,没有路径可以通过, 设置为0; 否则这个值为前一个节点的值
(dp[i-1][0]) == 0 || (obstacleGrid[i][0] == 1)判断为0或者1,加入进去
- 现在从obstacleGrid[1][1]开始遍历整个数组,如果某个个字初始化不包含任何障碍物,就把值赋予上方和左侧两个格子方案之和
let value = dp[i - 1][j] + dp[i][j - 1]
dp[i].append(value)
不包含障碍物上面.
6. 如果这个点是障碍物设置为0, 保证对后面的路径不产生贡献.
代码如下
func uniquePathsWithObstacles(_ obstacleGrid: [[Int]]) -> Int {
guard obstacleGrid.count > 0 else {return -1}
let rowLength = obstacleGrid.count //显示多少行
let verticalLength = obstacleGrid[0].count //显示多少列
var dp = [[Int]]()
if obstacleGrid[0][0] == 1 {//1代表有障碍
return 0
}
//初始化第一个元素,也就是dp[0][0]
var rowArr = [Int]()
for i in 0..<rowLength {
if i == 0 {
for j in 0..<verticalLength {
if j == 0 {
rowArr.append(1)
}
}
}
}
dp.append(rowArr)
//初始化第一列
for i in 1..<rowLength {
var vertical = [Int]()
let rowValue = (obstacleGrid[i][0] == 0 && dp[i-1][0] == 1) ? 1 : 0
for j in 0..<verticalLength {
if j == 0 {
vertical.append(rowValue)
}
}
dp.append(vertical)
}
//初始化第一行
for i in 1..<verticalLength {
let verticalValue = (obstacleGrid[0][i] == 0 && dp[0][i - 1] == 1) ? 1 : 0
dp[0].append(verticalValue)
}
//初始化其它元素
for i in 1..<rowLength {
for j in 1..<verticalLength {
if obstacleGrid[i][j] == 0 {
let value = dp[i - 1][j] + dp[i][j - 1]
dp[i].append(value)
} else {
dp[i].append(0)
}
}
}
return dp[rowLength-1][verticalLength-1]
}
上面运行代码如下:


上面就是不同路径关于动态规划下,swift完整代码,可以直接运行出来,代码也有注释,以后有新的解法,会持续更新,希望对大家有所帮助!!!