动态规划 || 有障碍物的不同路径 || 一个易错点 初始化

思路

易错点:初始化的时候,第一行,若有一列是 有障碍物的,那么后面的dp数组的值都为0,因为无法到达,这一列后面的格子只能通过向右走到达,而左边如果有障碍物,那么 右边的格子都无法到达,所以可以设置一个标志 hasObstacle,如果为1 ,表示在此之后的格子都无法到达。

解题过程

  • 设置dp数组 : dp[i][j] 含义:到达 第 i - 1 行和j -1 列所有的不同路径的数量;
  • 初始化dp数组:第一行和第一列只能通过向右走,和向下走到达,所以dp数组的第一行和第一列可以初始化,并且之后的dp数组的递推公式也需要用到第一行和第一列的数值来计算; 在赋值的过程中,需要注意,一旦出现障碍物,右边的格子均无法到达,所以dp设为0;
  • 求递推公式: dp[i][j] :
    • 如果[i][j]处有障碍物,那么dp[i][j]直接设为0,即无法达到;
    • 否则 因为机器人只能向下走或者向右走,那么到达[i][j]格子的路径数量可以由到达上一个格子的路径数量加上到达左边格子的路径数量的和推出来;(其实不用考虑上一个格子或者左边的格子的dp是否为0,如果为0,那么相加也为0,刚好符合题意

      复杂度

      • 时间复杂度: O(m + n)
      • 空间复杂度: O(m*n)
        int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obstacleGridColSize) {
        
            int row = obstacleGridSize;
            int col = *obstacleGridColSize;
        
            if(obstacleGrid[0][0] == 1 || obstacleGrid[row - 1][col - 1] == 1){
                return 0;
            }
        
            int** dp = (int**)malloc(sizeof(int*) * row);
            for(int i = 0;i < row; i ++){
                dp[i] = (int*)malloc(sizeof(int) * col);
                memset(dp[i], 0 , sizeof(int) * col);
            }
            
            int hasObstacle = 0;
            for(int i = 0; i < row; i ++){
                if(obstacleGrid[i][0] == 1){
                    hasObstacle = 1;
                }
                dp[i][0] = hasObstacle== 1 ? 0: 1;
            }
        
            hasObstacle = 0;
            for(int j = 0; j < col; j ++){
                if(obstacleGrid[0][j] == 1){
                    hasObstacle = 1;
                }     
                dp[0][j] = hasObstacle ==1 ? 0: 1;
            }
            for(int r = 1; r < row; r ++){
                for(int c = 1; c < col; c ++){
                    if(obstacleGrid[r][c] == 1){
                        dp[r][c] = 0;
                    }else{
                        dp[r][c] = dp[r][c - 1] + dp[r - 1][c];
                    }
                }
            }
            return dp[row - 1][col - 1];
        }
        
        作者:睡个好觉
        链接:https://leetcode.cn/problems/unique-paths-ii/solutions/3624561/dong-tai-gui-hua-you-zhang-ai-wu-de-bu-t-siqu/
        来源:力扣(LeetCode)
        著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

        评论
        添加红包

        请填写红包祝福语或标题

        红包个数最小为10个

        红包金额最低5元

        当前余额3.43前往充值 >
        需支付:10.00
        成就一亿技术人!
        领取后你会自动成为博主和红包主的粉丝 规则
        hope_wisdom
        发出的红包

        打赏作者

        睡个好觉(努力提升自己版)

        你的鼓励将是我创作的最大动力

        ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
        扫码支付:¥1
        获取中
        扫码支付

        您的余额不足,请更换扫码支付或充值

        打赏作者

        实付
        使用余额支付
        点击重新获取
        扫码支付
        钱包余额 0

        抵扣说明:

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

        余额充值