• 代码随想录算法训练营day39


    题目:62.不同路径、63. 不同路径 II

    参考链接:代码随想录

    62.不同路径

    思路:dp五部曲。首先dp数组,dp[i][j]表示从[0,0]出发,到达[i,j]路径的数量,我们要求dp[m,n];递归公式,即从dp[i-1][j]往下移动一步,或者dp[i][j-1]往右移动一步,这两者相加,如果i本来就为0,那么dp[i-1][j]就不存在,因为本来就在第一行只可能右移无法下移;初始化,dp[0][0]=1,还可以把第一行和第一列的全部初始化为1;递归顺序,从左到右从上往下;举例略。时间复杂度O(mn)。本题初始化和遍历实际上混在一起了。

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            int dp[m][n];//定义二维数组
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(i==0||j==0){//在第一行或第一列
                        dp[i][j]=1;
                    }
                    else{
                        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

    标答将初始化和转移分开了:

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            vector<vector<int>> dp(m, vector<int>(n, 0));
            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];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    一维优化方法不好理解。

    63. 不同路径 II

    思路:本题多了障碍,还是同样五部曲。dp数组依旧表示到[i,j]的路径数;在求递归公式的时候,如果没有障碍,递归公式正常进行,一旦遇到障碍点,说明这个地方无法到达,故将其置为0;初始化的时候要注意,第一行和第一列一旦遇到障碍,后面都要置0;遍历顺序和举例略。时间复杂度O(mn)。

    class Solution {
    public:
        int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
            int m=obstacleGrid.size();
            int n=obstacleGrid[0].size();
            vector<vector<int>> dp(m,vector<int>(n,0));//初始化全为0,我们尽可能使用vector
            for(int i=0;i<m;i++){
                if(obstacleGrid[i][0]==0){
                    dp[i][0]=1;
                }
                else{
                    break;
                }
            }
            for(int j=0;j<n;j++){
                if(obstacleGrid[0][j]==0){
                    dp[0][j]=1;
                }
                else{
                    break;
                }
            }
            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];
        }
    };
    
    • 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

    看标答发现可以在初始化的时候稍微优化下代码:

    class Solution {
    public:
        int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
            int m = obstacleGrid.size();
            int n = obstacleGrid[0].size();
    	if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) //如果在起点或终点出现了障碍,直接返回0
                return 0;
            vector<vector<int>> dp(m, vector<int>(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];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    一维空间优化版本:

    class Solution {
    public:
        int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
            if (obstacleGrid[0][0] == 1)
                return 0;
            vector<int> dp(obstacleGrid[0].size());
            for (int j = 0; j < dp.size(); ++j)
                if (obstacleGrid[0][j] == 1)
                    dp[j] = 0;
                else if (j == 0)
                    dp[j] = 1;
                else
                    dp[j] = dp[j-1];
    
            for (int i = 1; i < obstacleGrid.size(); ++i)
                for (int j = 0; j < dp.size(); ++j){
                    if (obstacleGrid[i][j] == 1)
                        dp[j] = 0;
                    else if (j != 0)
                        dp[j] = dp[j] + dp[j-1];
                }
            return dp.back();
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    Element Plus组件库中的input组件如何点击查看按钮时不可编辑,点击编辑时可编辑使用setup
    修改了windows dns配置,在wsl2中不生效
    一文讲明 Spring 的使用 【全网超详细教程】
    实战——Linux服务器CPU飙升原因排查
    椭球面的切平面
    Go 原子操作有哪些?
    React高级特性之HOC高阶组件
    【吊打面试官系列-Memcached面试题】memcached 最大的优势是什么?
    利用map的特性对数组进行操作
    【Linux】环境变量
  • 原文地址:https://blog.csdn.net/weixin_43390031/article/details/138128448