不同路径II --动态规划

谁都会走 提交于 2019-12-04 06:19:15

一个机器人位于一个 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. 向下 -> 向下 -> 向右 -> 向右

 

解法一: 动态规划

思想算法:

  1. 如果第一个格子点是obstacleGrid[0][0] 是 1, 说明有障碍物,那么机器人就不能做任何的移动,我们就直接返回0;
  2. 否则如果obstacleGrid[0][0] 是 0, 我们初始化这个值为1,然后继续算法;
  3. 遍历第一行,如果有个格子是为1,说明当前节点有障碍物,没有路径可走,设置为0;否则设这个值是前一个节点的值,如下:

    let verticalValue = (obstacleGrid[0][i] == 0 && dp[0][i - 1] == 1) ? 1 : 0

    dp[0].append(verticalValue)

  4. 遍历第一列,如果有一个格子初始值是1, 说明当前节点为障碍物,没有路径可以通过, 设置为0; 否则这个值为前一个节点的值
    (dp[i-1][0]) == 0 || (obstacleGrid[i][0] == 1)判断为0或者1,加入进去
  5. 现在从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完整代码,可以直接运行出来,代码也有注释,以后有新的解法,会持续更新,希望对大家有所帮助!!!

 
 

 

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!