一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

    机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

    现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

    可行的路径数II(有障碍)【动态规划】 - 图1
    PS: 网格中的障碍物和空位置分别用 10 来表示。
    说明:mn 的值均不超过 100。
    示例:

    输入:

    [

    [0,0,0],

    [0,1,0],

    [0,0,0]

    ]

    输出: 2

    解释:

    3x3 网格的正中间有一个障碍物。

    从左上角到右下角一共有 2 条不同的路径:

    1. 向右 -> 向右 -> 向下 -> 向下
    2. 向下 -> 向下 -> 向右 -> 向右

    解决思路:动态规划,状态(路径数)之间存在关系:

    1. int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
    2. int m = obstacleGrid.size();
    3. int n = obstacleGrid[0].size();
    4. // 状态定义:numberOfPath[i][j]表示从start到达(i, j)时路径数
    5. long numberOfPaths[m][n];
    6. // 状态初始化:
    7. numberOfPaths[0][0] = 1;
    8. // 状态转移:
    9. /*
    10. 1、如果(i, j)为障碍,则numberOfPaths[i][j] = 0
    11. 2、如果(i, j)不为障碍,则numberOfPaths[i][j]的值分为三种情况:
    12. 2.1: (i, j)位于行边界i==0; numberOfPaths[i][j] == numberOfPaths[i][j-1]
    13. 2.2: (i, j)位于列边界j==0; numberOfPaths[i][j] == numberOfPaths[i-1][j]
    14. 2.3:(i, j)位于其他位置; numberOfPaths[i][j] == numberOfPaths[i][j-1] + numberOfPaths[i-1][j]
    15. */
    16. for(int i=0; i<m; ++i)
    17. {
    18. for(int j=0; j<n; ++j)
    19. {
    20. if(obstacleGrid[i][j] == 1)
    21. numberOfPaths[i][j] = 0;
    22. else
    23. {
    24. if(i == 0 && j == 0)
    25. numberOfPaths[i][j] = 1;
    26. else if(i == 0)
    27. numberOfPaths[i][j] = numberOfPaths[i][j-1];
    28. else if(j == 0)
    29. numberOfPaths[i][j] = numberOfPaths[i-1][j];
    30. else
    31. numberOfPaths[i][j] = numberOfPaths[i-1][j] + numberOfPaths[i][j-1];
    32. }
    33. }
    34. }
    35. return numberOfPaths[m-1][n-1];
    36. }

    时间复杂度:O(mn);
    空间复杂度: O(mn); 可以优化