代码随想录算法训练营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];
    }
};

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

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

一维优化方法不好理解。

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

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

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

一维空间优化版本:

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();
    }
};
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值