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

文章目录

  • ❇️Day 39 第九章 动态规划 part02
    • ✴️今日任务
      • ❇️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. 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];
}

❇️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];
    }
}

随想录代码

遇到障碍之后可以不初始化,没赋值默认为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];
    }
}

你可能感兴趣的:(算法)