《算法设计与分析》第八周作业
标签(空格分隔): 课堂作业
姓名:李**
学号:16340114
题目:Unique Paths II(https://leetcode.com/problems/unique-paths-ii/description/)
题目概要
给定一个m*n的矩阵,矩阵中设有障碍物,有一个机器人在矩阵的左上角,机器人每一步只能往下或者往右移动,且不能通过障碍物,问机器人到达右下角的路径有多少条。
思路
这个题目可以用动态规划的思想去解决。把“到达右下角的路径数目”转换成“到达右下角左边的格子的路径数目”与“到达右下角上方的格子的路径数目”之和。用这个思路推导下去,就能得到这样的状态迁移方程:
pathNum[i][j] = pathNum[i - 1][j] + pathNum[i][j - 1]
(当pathNum[i - 1][j]或pathNum[i][j - 1]不存在时,其值为0)
特别地,如果左上角没有障碍物,那么从左上角到左上角的路径数为1。而有障碍物的格子的路径数为0。
具体实现
利用状态迁移方程编写方程就可以解决问题了。需要注意的是,如果使用递归的方式实现,不但效率低下, 还会重复计算某些状态。注意到,一个格子的路径数是依赖于该格子上方和左方的格子的路径数的,因此只需从上往下,从左到右计算矩阵中格子的路径数就可以得到答案,而不会出现重复计算格子路径数的情况。此外,额外处理左上角起点的格子和有障碍物的格子即可。
心得
这大概算是比较简单的动态规划问题了吧,感觉自己对动态规划的理解还不是很到位。把下周的课上完再去挑战更难的题目也许会轻松一点。
源码:
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid)
{
int height = obstacleGrid.size();
int width = obstacleGrid[0].size();
int** pathNum = new int* [height];
for (int i = 0; i < height; ++i)
{
pathNum[i] = new int [width];
}
pathNum[0][0] = !obstacleGrid[0][0];
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < width; ++j)
{
if (i == 0 && j == 0)
continue;
if (obstacleGrid[i][j] == 1)
pathNum[i][j] = 0;
else
pathNum[i][j] = ( i == 0 ? 0 : pathNum[i - 1][j] ) +
( j == 0 ? 0 : pathNum[i][j - 1]);
}
}
int answer = pathNum[height - 1][width - 1];
for (int i = 0; i < height; ++i)
{
delete [] pathNum[i];
}
delete [] pathNum;
return answer;
}
};