代码随想录算法训练营Day39|62.不同路径、63. 不同路径 II

目录

62.不同路径

思路

算法实现

63. 不同路径 II

前言

思路

算法实现

总结        


62.不同路径

题目链接

文章链接

思路

         机器人从(0 , 0) 位置出发,到(m - 1, n - 1)终点。依旧按照动态规划五部曲来进行:

1.确定dp数组以及下标的含义:

        由于题目给的是mXn的网格,因此可以创建二维数组dp[i][j],dp[i][j]:表示从(0, 0)出发,到(i, j)有dp[i][j]条不同的路径;

2.确定递推公式:

        要求dp[i][j],可以从两个方向考虑一个是dp[i - 1][j],另一个是dp[i][j - 1],dp[i - 1][j]表示的是从(0, 0)出发,到[i - 1, j]有几条路径,同理dp[i][j - 1]表示的是从(0, 0)出发,到[i, j - 1]有几条路径。因此,dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为dp[i][j]只有这两个方向过来。

3.初始化dp数组:

        因为机器人只能向下或向左移动,从(0, 0)的位置到(i, 0)的路径只有一条,dp[i][0]都要初始化为1,dp[0][j]也同理。

4.确定遍历顺序:

        从递推公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1]可以看出,当前路线一定是从左和上方得到的,那么从左到右一层一层遍历就可以了。这样就可以保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值的。

5.举例推导dp数组:

        自己尝试举几个例子将dp数组写出来验证。

算法实现

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector> dp(m, vector(n, 0));
        // 初始化dp数组
        for (int i = 0; i < m; i++) dp[i][0] = 1;
        for (int j = 0; j < n; j++) dp[0][j] = 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

题目链接

文章链接

前言

         本题也是一题路径搜索类题,在上一题的基础上在网格中增加了一些障碍,求在有障碍的情况下路线的条数。

思路

        有障碍的情况,其实就是标记对应的dp数组保持初始值(0)就可以了。再以动态规划五部曲进行:

1.确定dp数组以及下标含义:

        同上题一样dp数组表示从(0, 0)出发,到(i, j)有dp[i][j]条不同的路径;

2.确定递推公式:

        大方向上依然是dp[i][j] = dp[i - 1][j] + dp[i][j - 1],只是要避开有障碍的情况;

3.初始化dp数组:

        在初始化dp[i][0]和dp[0][j]的时候,遇到障碍就停止初始化;

4.确定遍历顺序:

        依然是前序遍历;

5.举例推导dp数组:

        略。

算法实现

class Solution {
public:
    int uniquePathsWithObstacles(vector>& obstacleGrid) {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();
        vector> dp(m, vector (n, 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++) {
                if (obstacleGrid[i][j] == 1) continue;
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m - 1][n - 1];
    }
};

总结        

        今天的两题任务量不大,但也加深了动态规划五部曲的使用,对于dp二维数组的操作也有所了解,受益颇多!

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