LeetCode 63. Unique Paths II(C++, 动态规划)

题目:A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).Now consider if some obstacles are added to the grids. How many unique paths would there be?
题目地址
在这里插入图片描述

An obstacle and empty space is marked as 1 and 0 respectively in the grid.
Note: m and n will be at most 100.
Example 1:

Input:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]

Output: 2
Explanation:
There is one obstacle in the middle of the 3x3 grid above.
There are two ways to reach the bottom-right corner:

  1. Right -> Right -> Down -> Down
  2. Down -> Down -> Right -> Right

思路1(DP Accepted): 使用动态规划的一般步骤是:
①找到一个好的状态表示
②根据题目对状态进行初始化
③最后根据递推公式递推出所有的状态。

这题的题意是给定一幅地图,1表示障碍,0表示可以通过,求从地图左上角到右下角得通路数。
①状态表示:如果使用动态规划可以建立一个二维数组dp两个维度大小都设为101(题目说最大为100,一般略大一些),二维数组每个位置的值都为在给定的地图上从左上角到当前位置的通路数。 设地图行数为r,列数为c,这样数组dp[r-1][c-1]的值即为从地图左上角到地图右下角的通路数。

②设给定的地图为obstacleGrid,根据obstacleGrid左上角的值如果为0则表示从左上角到当前位置(0,0)有一种走法,所以设置dp[0][0]=1,否则设置dp[0][0]=0。因为题目规定只能朝右边和下边走,所以:
第一行的第i列的递推公式为:if(obstacleGrid[0][i]==0&&dp[0][i-1]) dp[0][i] = 1 else dp[0][i] = 0
第一列的第i行的递推公式为:if(obstacleGrid[i][0]==0&&dp[i-1][0]) dp[0][i] = 1 else dp[0][i] = 0

③其他位置第i行第j列的递推公式为:if(obstacleGrid[i][j]==0) dp[i][j] = dp[i-1][j] + dp[i][j-1] else dp[i][j] = 0,即如果当前位置没有障碍,则左上角到当前位置通路数等于左上角到当前位置左边通路数加到当前位置上边通路数。如果有障碍,则从左上角到当前位置数为0。

代码(C++)

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        const int rows = obstacleGrid.size();
        const int cols = obstacleGrid[0].size();
        int (*dp)[101] = new int[101][101];
        
        if(obstacleGrid[0][0]==0)//初始化第一个位置
            dp[0][0] = 1;
        else
            dp[0][0] = 0;
        for(int i = 1; i<cols; i++){//初始化第一行
            if(dp[0][i-1]==1 && obstacleGrid[0][i]==0){
                dp[0][i] = 1;
            }
            else{
                dp[0][i] = 0;
            }
        }
        
        for(int i = 1; i<rows; i++){//初始化第一列
            if(dp[i-1][0]==1&&obstacleGrid[i][0]==0){
                dp[i][0] = 1;
            }
            else 
                dp[i][0] = 0;
        }
        
        for(int i = 1; i < rows; i++){//递推
            for(int j = 1; j < cols; j++){
                if(obstacleGrid[i][j] == 0){
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
                }   
                else
                    dp[i][j] = 0;
            }
        }
     
        return dp[rows-1][cols-1];     
    }  
};

//dp[i][j] = dp[i-1][j]+d[i][j-1] if obstacleGrid[i][j] = 0
//else dp[i][j] = 0 

思路2: 深度优先搜索,但是超时了(数据规模有100*100),方法应该对的,当做参考,如果不对欢迎指出。

代码DFS/C++

//递归超时解决方案
class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int result = 0;
        dfs(obstacleGrid, 0, 0, result);
        return result;
    }
    
    void dfs(vector<vector<int>>& obstacleGrid, int x, int y, int & result){//x和y为机器人现在所在位置
        int rows = obstacleGrid.size();
        int cols = obstacleGrid[0].size();
        if(obstacleGrid[rows-1][cols-1] == 1){//右下角位置为1
            result = 0;
            return;
        }
        if(obstacleGrid[0][0]==1){//起始位置为1
            result = 0;
            return;
        }
        if(x==rows-1 && y==cols-1 &&obstacleGrid[x][y]==0){
            result++;
            return ;
        }
        
        if(x+1<rows && obstacleGrid[x+1][y]==0)
            dfs(obstacleGrid, x+1, y, result);
        
        if(y+1<cols && obstacleGrid[x][y+1] == 0)
            dfs(obstacleGrid, x, y+1, result);
        return ;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值