63. 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
https://www.youtube.com/watch?v=8v-dX6ato_Y
方法1: DP
这种用[n + 1, m + 1]表格存储的方法非常考验处理边界
code1
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if (obstacleGrid.size() == 0) return 0;
int n = obstacleGrid.size();
int m = obstacleGrid[0].size();
vector<vector<long>> myTable(n, vector<long> (m, 0));
// myTable[1][1] = 1;
for (int i = 1; i < n + 1; i++){
if (obstacleGrid[i - 1][0] == 1)
break;
myTable[i][1] = 1;
}
for (int j = 1; j < m + 1; j++){
if (obstacleGrid[0][j - 1] == 1)
break;
myTable[1][j] = 1;
}
for (int i = 2; i < n + 1; i++){
for (int j = 2; j < m + 1; j++){
if (obstacleGrid[i - 1][j - 1] == 1)
myTable[i][j] = 0;
else
myTable[i][j] = myTable[i - 1][j] + myTable[i][j - 1];
}
}
return myTable[n][m];
}
};
code2
用[n, m]大小的myTable来存储,边界问题比较简单
如果myTable的类型用int会造成overflow。
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if (obstacleGrid.size() == 0) return 0;
int n = obstacleGrid.size();
int m = obstacleGrid[0].size();
vector<vector<long>> myTable(n, vector<long> (m, 0));
for (int i = 0; i < n; i++){
if (obstacleGrid[i][0] == 1)
break;
myTable[i][0] = 1;
}
for (int j = 0; j < m; j++){
if (obstacleGrid[0][j] == 1)
break;
myTable[0][j] = 1;
}
for (int i = 1; i < n ; i++){
for (int j = 1; j < m; j++){
if (obstacleGrid[i][j] == 1)
myTable[i][j] = 0;
else
myTable[i][j] = myTable[i - 1][j] + myTable[i][j - 1];
}
}
return myTable[n - 1][m - 1];
}
};
方法2: recursion + memoize
code
not working yet
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if (obstacleGrid.size() == 0) return 0;
int n = obstacleGrid.size();
int m = obstacleGrid[0].size();
vector<vector<long>> myTable(n + 1, vector<long> (m + 1, 0));
return paths(m, n , obstacleGrid);
}
private:
vector<vector<long>> myTable;
int paths(int x, int y, vector<vector<int>> & obstacleGrid){
if (x <= 0 || y <= 0) return 0;
if (x == 1 && y == 1) return 1- obstacleGrid[0][0];
if (myTable[y][x] != INT_MIN) return myTable[y][x];
if (obstacleGrid[y - 1][x - 1] == 1)
myTable[y][x] = 0;
else
myTable[y][x] = paths(x, y - 1, obstacleGrid) + paths(x - 1, y, obstacleGrid);
return myTable[y][x];
}
};