目 录CONTENT

文章目录

63. 不同路径 II

小王同学
2023-12-30 / 0 评论 / 0 点赞 / 40 阅读 / 0 字

63. 不同路径 II

力扣传送门(opens new window)

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 1 和 0 来表示。

示例 1:

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

示例 2:

  • 输入:obstacleGrid = [[0,1],[0,0]]
  • 输出:1

提示:

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

解决思路:

首先说一下还是使用动态规划来做,只不过这道题目里面加了障碍物,这里我在做的时候犯了一个错误,就是初始化的时候,如果第一行或者第一列已经出现1障碍物之后,那么就不可以再进行走下去了

刚开始我写的初始化的代码是:

 //初始化第一列
        for(int i = 0;i < row;i++){
            if(obstacleGrid[i][0] == 1){
                dp[i][0] = 0; 
            }else{
                dp[i][0] = 1; 
            }
      
        }
        //初始化第一行
        for(int i = 0;i < col;i++){
            if(obstacleGrid[0][i] == 1){
                dp[0][i] = 0; 
            }else{
                dp[0][i] = 1; 
            }
        }

这里明显是错误的。原因就是else的部分,如果遇到障碍物,则后续位置都无法到达,直接跳出循环就可以了。

具体的思路为:

  1. 创建一个二维数组 dp,其中 dp[i][j] 表示从起点到达网格 (i, j) 的不同路径数目。
  2. 初始化起点的路径数目为1,因为只有一种方式可以到达起点。
  3. 更新第一列的路径数目,如果这个格子没有障碍物,则该格子的路径数目为1。
  4. 更新第一行的路径数目,如果这个格子没有障碍物,则该格子的路径数目为1。
  5. 从左上角开始,逐行逐列计算路径数目。对于每个格子,如果该格子没有障碍物,则路径数目等于左侧格子的路径数目加上上方格子的路径数目。
  6. 如果如果该格子有障碍物,则直接跳过。
  7. 返回终点的路径数目作为最终的答案。

需要注意的是,如果某个格子上有障碍物,则该格子的路径数目为0,表示无法通过该格子。在代码中,我们通过判断 obstacleGrid[i][j] 是否为0来判断是否有障碍物。

代码实现:

/**
 * 63. 不同路径 II
 */
public class UniquePathsII {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        if (obstacleGrid == null || obstacleGrid.length == 0) {
            return 0;
        }
        int row = obstacleGrid.length;
        int col = obstacleGrid[0].length;
        int[][] dp = new int[row][col];

        // 初始化第一列
        for (int i = 0; i < row; i++) {
            if (obstacleGrid[i][0] == 0) {
                dp[i][0] = 1;
            } else {
                // 如果遇到障碍物,则后续位置都无法到达,直接跳出循环
                break;
            }
        }
        // 初始化第一行
        for (int i = 0; i < col; i++) {
            if (obstacleGrid[0][i] == 0) {
                dp[0][i] = 1;
            } else {
                // 如果遇到障碍物,则后续位置都无法到达,直接跳出循环
                break;
            }
        }

        for (int i = 1; i < row; i++) {
            for (int j = 1; j < col; j++) {
                if (obstacleGrid[i][j] == 1) {
                    // 障碍物位置的路径数设为0
                    dp[i][j] = 0;
                } else {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }
            }
        }
        return dp[row - 1][col - 1];
    }
}

首先,我们可以用一个2D网格来表示给定的障碍物网格。其中0表示空地,1表示障碍物。我们需要计算从起点到终点的不同路径数目。

1.创建一个与给定网格相同大小的二维数组 dp,用于保存路径数目。

dp = [[0, 0, 0],
      [0, 0, 0],
      [0, 0, 0]]

2.更新第一列的路径数目。如果某个格子上方没有障碍物,则该格子的路径数目与上方格子的路径数目相同。否则,如果上方格子有障碍物,则无法通过该格子。

dp = [[1, 0, 0],
      [1, 0, 0],
      [1, 0, 0]]

3.更新第一行的路径数目。如果某个格子左侧没有障碍物,则该格子的路径数目与左侧格子的路径数目相同。否则,如果左侧格子有障碍物,则无法通过该格子。

dp = [[1, 1, 1],
      [1, 0, 0],
      [1, 0, 0]]

4.从左上角开始,逐行逐列计算路径数目。对于每个格子,如果该格子没有障碍物,则路径数目等于左侧格子的路径数目加上上方格子的路径数目。如果该格子有障碍物,则路径数目为0。

dp = [[1, 1, 1],
      [1, 0, 1],
      [1, 1, 2]]

5.终点的路径数目即为最终的答案。在这个例子中,终点的路径数目为2。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区