当前位置:   article > 正文

【代码随想录算法训练营Day39】62.不同路径;63. 不同路径 II

【代码随想录算法训练营Day39】62.不同路径;63. 不同路径 II

❇️Day 39 第九章 动态规划 part02

✴️今日任务

今天开始逐渐有 dp的感觉了,题目不多,就两个 不同路径,可以好好研究一下

  • 62.不同路径
  • 63.不同路径 II

❇️62.不同路径

  • 本题大家掌握动态规划的方法就可以。 数论方法 有点非主流,很难想到。
  • 题目链接:https://leetcode.cn/problems/unique-paths/
  • 视频讲解:https://www.bilibili.com/video/BV1ve4y1x7Eu
  • 文章链接:https://programmercarl.com/0062.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84.html

自己的思路

  1. dp数组及下标的含义
    定义一个二维数组dp[i][j]表示机器人到第i行第j列的格有dp[i][j]种路径
    i的最大值为m,j的最大值为n
    int dp[][] = new int[m + 1][n + 1];
  2. 递归函数
    当前格可以通过上面一格往下或左面一格往右
    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
  3. dp数组初始化
    dp[0][], dp[][0]相当于在网格上面和左边分别多增加一行一列
    dp[1][1] = 1; dp[0][] = 0; dp[][0] = 0;
  4. 遍历顺序
    先从上到下再从左到右
    dp[1][1]->dp[2][1]->···->dp[m][1]->dp[1][2]->dp[2][2]->···
    或从左到右在从上到下
    dp[1][1]->dp[1][2]->···->dp[1][n]->dp[2][1]->dp[2][2]->···
  5. 打印dp数组

自己的代码

class Solution {
    public int uniquePaths(int m, int n) {
        int dp[][] = new int[m + 1][n + 1];
        dp[1][1] = 1;
        for (int i = 0; i <= m; i++) {
            dp[i][0] = 0;
        }
        for (int j = 0; j <= n; j++) {
            dp[0][j] = 0;
        }
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if(i == 1 && j == 1) continue;
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
            //System.out.println(Arrays.toString(dp[i]));
        }
        return dp[m][n];
    }
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

随想录思路

  1. dp数组及下标的含义
    定义一个二维数组dp[i][j]表示机器人到第i行第j列的格有dp[i][j]种路径
    i的最大值为m - 1,j的最大值为n - 1
    int dp[][] = new int[m][n];
  2. 递归函数
  3. dp数组初始化
    dp[0][], dp[][0]都初始化为1
  4. 遍历顺序
  5. 打印dp数组

随想录代码

/**
 * 1. 确定dp数组下标含义 dp[i][j] 到每一个坐标可能的路径种类
 * 2. 递推公式 dp[i][j] = dp[i-1][j] dp[i][j-1]
 * 3. 初始化 dp[i][0]=1 dp[0][i]=1 初始化横竖就可
 * 4. 遍历顺序 一行一行遍历
 * 5. 推导结果 。。。。。。。。
 *
 * @param m
 * @param n
 * @return
 */
public static int uniquePaths(int m, int n) {
    int[][] dp = new int[m][n];
    //初始化
    for (int i = 0; i < m; i++) {
        dp[i][0] = 1;
    }
    for (int i = 0; i < n; i++) {
        dp[0][i] = 1;
    }

    for (int i = 1; i < m; i++) {
        for (int j = 1; j < n; j++) {
            dp[i][j] = dp[i-1][j]+dp[i][j-1];
        }
    }
    return dp[m-1][n-1];
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

❇️63. 不同路径 II

  • 题目链接:https://leetcode.cn/problems/unique-paths-ii/
  • 视频讲解:https://www.bilibili.com/video/BV1Ld4y1k7c6
  • 文章链接:https://programmercarl.com/0063.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84II.html

自己的思路

  1. dp数组及下标的含义
    定义一个二维数组dp[i][j]表示机器人到第i行第j列的格有dp[i][j]种路径
    i的最大值为m - 1,j的最大值为n - 1
    int dp[][] = new int[m][n];
  2. 递归函数
    当前格可以通过上面一格往下或左面一格往右
    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
  3. dp数组初始化
    当obstacleGrid[0][]和obstacleGrid[][0]不为1时对应的dp[0][]和dp[][0]为1,否则为0
    ❗当前面或上面有障碍那后面都得初始化为0
  4. 遍历顺序
    先从左到右再从上到下
  5. 打印dp数组

自己的代码

踩坑:
初始化错误

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int dp[][] = new int[obstacleGrid.length][obstacleGrid[0].length];
        //初始化
        for (int i = 0; i < dp.length; i++) {
            if(obstacleGrid[i][0] == 0){
                dp[i][0] = 1;
            }else{
                for (int j = i; j < dp.length; j++) {
                    dp[j][0] = 0;
                }
                break;
            }
        }
        for (int j = 0; j < dp[0].length; j++) {
            if(obstacleGrid[0][j] == 0){
                dp[0][j] = 1;
            }else{
                for (int i = j; i < dp[0].length; i++) {
                    dp[0][i] = 0;
                }
                break;
            }
        }
        // for (int i = 0; i < dp.length; i++) {
        //     System.out.println("*"+Arrays.toString(dp[i]));
        // }
        // System.out.println(Arrays.toString(dp[0]));
        for (int i = 1; i < dp.length; i++) {
            for (int j = 1; j < dp[0].length; j++) {
                if(obstacleGrid[i][j] == 0){
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }else{
                    dp[i][j] = 0;
                }
            }
            //System.out.println(Arrays.toString(dp[i]));
        }
        return dp[dp.length - 1][dp[0].length - 1];
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

随想录代码

遇到障碍之后可以不初始化,没赋值默认为0
起始有障碍or终止有障碍直接返回0
可以在for循环中间添加条件

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        int[][] dp = new int[m][n];

        //如果在起点或终点出现了障碍,直接返回0
        if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) {
            return 0;
        }

        for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {
            dp[i][0] = 1;
        }
        for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {
            dp[0][j] = 1;
        }

        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = (obstacleGrid[i][j] == 0) ? dp[i - 1][j] + dp[i][j - 1] : 0;
            }
        }
        return dp[m - 1][n - 1];
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/209680
推荐阅读
相关标签
  

闽ICP备14008679号