daily leetcode - unique-paths-ii - !

题目地址

https://leetcode.com/problems/unique-paths-ii/

题目描述

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:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right

思路

这道题是之前那道 Unique Paths 的延伸,在路径中加了一些障碍物,还是用动态规划 Dynamic Programming 来解,使用一个二维的 dp 数组,大小为 (m+1) x (n+1),这里的 dp[i][j] 表示到达 (i-1, j-1) 位置的不同路径的数量,那么 i 和 j 需要更新的范围就是 [1, m] 和 [1, n]。状态转移方程跟之前那道题是一样的,因为每个位置只能由其上面和左面的位置移动而来,所以也是由其上面和左边的 dp 值相加来更新当前的 dp 值,如下所示:

dp[i][j] = dp[i-1][j] + dp[i][j-1]

这里就能看出来初始化 d p 数组的大小为 (m+1) x (n+1),是为了 handle 边缘情况,当 i 或 j 为 0 时,减 1 可能会出错。当某个位置是障碍物时,其 dp 值为 0,直接跳过该位置即可。这里还需要初始化 dp 数组的某个值,使得其能正常累加。当起点不是障碍物时,其 dp 值应该为 1,即 dp[1][1] = 1,由于其是由 dp[0][1] + dp[1][0] 更新而来,所以二者中任意一个初始化为 1 即可。由于之后 LeetCode 更新了这道题的 test case,使得使用 int 型的 dp 数组会有溢出的错误,所以改为使用 long 型的数组来避免 overflow.

关键点解析

代码

解法一:

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        if (obstacleGrid.empty() || obstacleGrid[0].empty() || obstacleGrid[0][0] == 1) return 0;
        int m = obstacleGrid.size(), n = obstacleGrid[0].size();
        vector<vector<long>> dp(m + 1, vector<long>(n + 1, 0));
        dp[0][1] = 1;
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (obstacleGrid[i - 1][j - 1] != 0) continue;
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m][n];
    }
};

或者我们也可以使用一维 dp 数组来解,省一些空间,参见代码如下:

解法二:

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        if (obstacleGrid.empty() || obstacleGrid[0].empty() || obstacleGrid[0][0] == 1) return 0;
        int m = obstacleGrid.size(), n = obstacleGrid[0].size();
        vector<long> dp(n, 0);
        dp[0] = 1;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (obstacleGrid[i][j] == 1) dp[j] = 0;
                else if (j > 0) dp[j] += dp[j - 1];
            }
        }
        return dp[n - 1];
    }
};

本文参考自:
https://github.com/grandyang/leetcode/ &
https://github.com/azl397985856/leetcode


标题: daily leetcode - unique-paths-ii - !
文章作者: lonuslan
文章链接: https://louislan.com/articles/2020/02/10/1581319461442.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hi I'm LouisLan
    评论
    0 评论
avatar

取消