题目: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:
- Right -> Right -> Down -> Down
- 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 ;
}
};