leetcode-63 不同路径 II

给定一个 m x n 的整数数组 grid。一个机器人初始位于 左上角(即 grid[0][0])。机器人尝试移动到 右下角(即 grid[m - 1][n - 1])。机器人每次只能向下或者向右移动一步。
网格中的障碍物和空位置分别用 1 和 0 来表示。机器人的移动路径中不能包含 任何 有障碍物的方格。
返回机器人能够到达右下角的不同路径数量。
测试用例保证答案小于等于 2 * 109。

示例 1:
image
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:

  1. 向右 -> 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右 -> 向右

示例 2:
image
输入:obstacleGrid = [[0,1],[0,0]]
输出:1

提示:
m == obstacleGrid.length
n == obstacleGrid[i].length
1 <= m, n <= 100
obstacleGrid[i][j] 为 0 或 1

实现:

func uniquePathsWithObstacles(obstacleGrid [][]int) int {

    // 获取网格grid的长宽
    m,n := len(obstacleGrid),len(obstacleGrid[0])

    // 如果网格左上角顶点有障碍物(值为1),则不存在可以通过右下角的路径,故返回0
    if obstacleGrid[0][0] == 1 {
        return 0
    }

    // 定义dp,用来存储到达不同右下角位置时的路径数
    dp := make([][]int, m)
    for i := range m {
        dp[i] = make([]int, n)
    }
    
    // 初始化dp,左顶点置为1(表示该左顶点无障碍物,可以通行,同时因为是顶点,所以本身也代表一条路径)
    dp[0][0] = 1
    // 初始化dp第一列,如果网格遍历位置无障碍物(值为0),且上一行位置存在路径(dp[i-1]值大于0),则dp[i][0]置为1,反之为0
    for i:=1; i<m; i++ {
        if obstacleGrid[i][0] == 0 && dp[i-1][0] == 1 {
            dp[i][0] = 1
        } else {
            dp[i][0] = 0
        }
    }
    // 初始化dp第一行,如果网格遍历位置无障碍物(值为0),且左边位置存在路径([j-1]值大于0),则dp[0][j]置为1,反之为0
    for j:=1; j<n; j++ {
        if obstacleGrid[0][j] == 0 && dp[0][j-1] == 1 {
            dp[0][j] = 1
        } else {
            dp[0][j] = 0
        }
    }

    // 遍历dp,如果当前位置无障碍物,则当前位置路径数,等于上方节点加左边节点值的和(因为机器人规定只能往下和往右方向走),有障碍物则路径数为0
    for i:=1; i<m; i++ {
        for j:=1; j<n; j++ {
            if obstacleGrid[i][j] == 0 {
                dp[i][j] = dp[i-1][j] + dp[i][j-1]
            } else {
                dp[i][j] = 0
            }
        }
    }

    // 返回右下角顶点路径数
    return dp[m-1][n-1]
}
posted @ 2024-10-13 17:49  505donkey  阅读(58)  评论(0)    收藏  举报