力扣63-不同路径 II(Java详细题解)

题目链接:63. 不同路径 II - 力扣(LeetCode)

前情提要:

本题跟力扣62不同路径很像,就是会有障碍物阻碍。其实就是初始化和处理逻辑有所变化。建议大家可以先做一下力扣62.

题目链接:62. 不同路径 - 力扣(LeetCode) 题解链接:力扣62-不同路径(Java详细题解)-CSDN博客

因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。

dp五部曲。

1.确定dp数组和i下标的含义。

2.确定递推公式。

3.dp初始化。

4.确定dp的遍历顺序。

5.如果没有ac打印dp数组 利于debug。

每一个dp题目如果都用这五步分析清楚,那么这道题就能解出来了。

题目思路:

直接按照dp五部曲走。

1.确定dp数组和i下标的含义。

该题要求我们返回到达右下角一共有多少中不同的路径。

而且本题是在一个网格内,所以本题的dp数组是二维的。

那么dp[i] [j]就是指到达第i行j列的不同的路径。

2.确定递推公式。

题目明确,机器人每次只能向下或者向右移动一步。

所以我们第i行j列只能由它的上一行或者左边的一列得出。

dp[i] [j] 只能由 dp[i - 1] [j] 或 dp[i] [j - 1]得出。

那具体怎么得出呢,其实是他俩想加的和。

即本格的不同路径条数是由他上一行格的路径条数和左边一列的路径条数。

3.dp的初始化。

机器人只能从向下或者向右移动。而且dp[i] [j] 只能由 dp[i - 1] [j] 或 dp[i] [j - 1]得出。即本格只能从他的上一行格和左列格的路径得出,所以我们肯定要知道最上边一行和最左边一列的路径。

即dp[i] [0] 和 dp[0] [i]的路径数。

他们的路径其实为1。

为啥为1呢?

机器人只能向右或者向下移动,最上面一行其实就是机器人一直向右移动,其实就一条路径能这样走。最左边一列也同理。

所以do[i] [0] = 1,dp[0] [i] = 1;

但是可能会遇到障碍物,障碍物所在的那一格肯定路径数为0

而在第一行和最左一列中遇到了障碍物,障碍物后面的格应该全赋值给0,或者不处理。因为机器人只能向下一格或者向右一格,当一行中出现障碍,我们就到达不了障碍后面的位置了。

为什么到达不了,绕一下不就好了?

肯定有朋友会这么想,但其实是到达不了的,如果绕一下的话就必须要向上或者向左移动了而机器人只能向下或者向右。

所以当遇到障碍后的所有格数不处理。

在这里插入图片描述

4.dp遍历顺序。

其实dp的初始顺序可以有递推公式看出来。每一个台阶只能从他的上一个或者左列的得出。所以dp的遍历顺序是每一行从左往右,每一列从上到下。

5.打印dp数组。

如果没有出现差错,我们就可以不用打印,因为我是写题解,所以我就不添加核心代码以外的代码,不然代码显的有些冗余。

举个例子。

在这里插入图片描述

以上五步都做完,那么此题的代码就可以写出来了。

最终代码:

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        //本题与不同路径最大的区别就是有障碍 如果有障碍就直接跳过该地方
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        if(obstacleGrid[0][0] == 1 || obstacleGrid[m - 1][n - 1] == 1)return 0;
        int[][] dp = new int [m][n];
        //遇到障碍前处理
        for(int i = 0;i < m && obstacleGrid[i][0] == 0;i ++){
            dp[i][0] = 1;
        }
        for(int i = 0;i < n && obstacleGrid[0][i] == 0;i++){
            dp[0][i] = 1;
        }
        for(int i = 1;i < m;i ++){
            for(int j = 1; j < n;j ++){
                //如果不为障碍再递推
                if(obstacleGrid[i][j] == 0){
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }
            }
        }
        return dp[m - 1][n - 1];

    }
}

这一篇博客就到这了,如果你有什么疑问和想法可以打在评论区,或者私信我。

我很乐意为你解答。那么我们下篇再见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值