Unique Paths II
Follow up for "Unique Paths": 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. For example, There is one obstacle in the middle of a 3x3 grid as illustrated below. [ [0,0,0], [0,1,0], [0,0,0] ] The total number of unique paths is 2. Note: m and n will be at most 100.
分析
题目的意思是,有一个m*n的格子,机器人从左上方的(1,1)为起点,每一步只能往下走或者往右走,格子可能有障碍不能通过,‘1’表示有障碍,‘0’表示没有障碍。走到右下角一共有多少条路?
这道题目之前的“Unique Paths”的变形,上一道题既可以用DP解答,也可以用排列解. 但是这道题用DP会好很多:障碍物若是只有几个,且个数是固定的,可以用排列来做。比如当只有1个障碍物时,将无障碍的路总数量-经过障碍点的路的数量;2个障碍物时,无障碍的路总数量-经过障碍1的路的数量-经过障碍2的路数量+同时经过2个障碍的路数量。由此可看,当障碍物一多,或者障碍物不确定时,用排列非常麻烦。
下面用DP来解决这个问题:
* 由题意值,走的方向只有两个,右和下。所以,任意位置map[i][j]的上一步可能是两个位置: * map[i-1][j]或者map[i][j-1],所以可以列出描述式: * 1、map[i][j]=0 obstacle[i][j]为1 * 2、map[i][j]=map[i-1][j] obstacle[i][j], obstacle[i-1][j]为0,obstacle[i][j-1]为1 * 3、map[i][j]=map[i][j-1] obstacle[i][j],obstacle[i][j-1]为0,obstacle[i-1][j]为1 * 4、map[i][j]=map[i-1][j]+map[i][j-1] obstacle[i-1][j],obstacle[i][j-1],obstacle[i][j]为0 * 可以进一步化简 * 1、map[i][j]=0 obstacle[i][j]为1 * 2、map[i][j]=map[i-1][j]+map[i][j-1] obstacle[i][j]为0
Code
class Solution {
public:
/*
* 障碍物若是只有几个,且个数是固定的,可以用排列来做。比如当只有1个障碍物时,将无障碍的路总数量-经过
* 障碍点的路的数量;2个障碍物时,无障碍的路总数量-经过障碍1的路的数量-经过障碍2的路数量+同时经过2个障碍
* 的路数量。由此可看,当障碍物一多,或者障碍物不确定时,用排列非常麻烦。
* 下面用DP来解决这个问题
* 由题意值,走的方向只有两个,右和下。所以,任意位置map[i][j]的上一步可能是两个位置:
* map[i-1][j]或者map[i][j-1],所以可以列出描述式:
* 1、map[i][j]=0 obstacle[i][j]为1
* 2、map[i][j]=map[i-1][j] obstacle[i][j], obstacle[i-1][j]为0,obstacle[i][j-1]为1
* 3、map[i][j]=map[i][j-1] obstacle[i][j],obstacle[i][j-1]为0,obstacle[i-1][j]为1
* 4、map[i][j]=map[i-1][j]+map[i][j-1] obstacle[i-1][j],obstacle[i][j-1],obstacle[i][j]为0
* 可以进一步化简
* 1、map[i][j]=0 obstacle[i][j]为1
* 2、map[i][j]=map[i-1][j]+map[i][j-1] obstacle[i][j]为0
* */
int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(obstacleGrid.size() == 0)
return 0;
//如果起点有障碍
if(obstacleGrid[0][0]) return 0;
int rows = obstacleGrid.size();
int cols = obstacleGrid[0].size();
//存储中间经过的所有位置的路的条数
int tables[101][101] = {0};
//起点赋值(起点有障碍的情况已在函数开始处理了)
tables[1][1] = 1;
for(int i = 1; i <= rows; i++)
{
for(int j = 1; j <= cols; j++)
{
if(i==1&&j==1)
continue;
//如果这个点有障碍,表示不能通过,赋值0
if(obstacleGrid[i-1][j-1])
tables[i][j] = 0;
//没有障碍物,可以通过
else
tables[i][j] = tables[i-1][j] + tables[i][j-1];
}
}
return tables[rows][cols];
}
};