zoukankan      html  css  js  c++  java
  • 不同路径II --动态规划

    一个机器人位于一个 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完整代码,可以直接运行出来,代码也有注释,以后有新的解法,会持续更新,希望对大家有所帮助!!!

     
     
  • 相关阅读:
    jQuery基础之让出$,与其他库共存
    什么是闭包
    绑定repeater时三目运算加特殊结果处理
    将同一张表出来的两部分内容再合成一张表
    后台往前台写弹窗代码不显示
    固定行列转换加分段统计
    js调用后台方法(如果你能容忍执行的后台方法变成一个常量)
    javascript遍历数组
    基于SpringMVC框架使用ECharts3.0实现折线图,柱状图,饼状图,的绘制(上篇)
    echarts
  • 原文地址:https://www.cnblogs.com/guohai-stronger/p/11831334.html
Copyright © 2011-2022 走看看