《算法设计与分析》第八周作业

《算法设计与分析》第八周作业

标签(空格分隔): 课堂作业

姓名:李**
学号: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;
    }
};

猜你喜欢

转载自blog.csdn.net/Ray0758/article/details/83477045