/**************************************************************************
*
* 63. [Unique Paths II](https://leetcode.com/problems/unique-paths-ii/)
*
* Now consider if some obstacles are added to the grids. How many unique paths would there be ?
*
* Example :
* 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
*
**************************************************************************/
///
///
/// Approach 1: Dynamic Programming
int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obstacleGridColSize){
if (NULL == obstacleGrid || NULL == obstacleGridColSize || \
*obstacleGridColSize < 1 ||obstacleGridSize < 1 || obstacleGrid[0][0])
return 0;
int rows = obstacleGridSize;
int cols = *obstacleGridColSize;
int **f = (int **)calloc(rows, sizeof(int *));
for (int i = 0; i < rows; i++)
f[i] = (int *)calloc(cols, sizeof(int));
f[0][0] = 1;
// 初始化第一行
for (int i = 1; i < cols; i++) {
if (f[0][i-1] == 0 || obstacleGrid[0][i])
f[0][i] = 0;
else
f[0][i] = 1;
}
// 初始化第一列
for (int i = 1; i < rows; i++) {
if (f[i-1][0] == 0 || obstacleGrid[i][0])
f[i][0] = 0;
else
f[i][0] = 1;
}
for (int i = 1; i < rows; i++) {
for (int j = 1; j < cols; j++) {
if (obstacleGrid[i][j])
f[i][j] = 0;
else
f[i][j] = f[i][j-1] + f[i-1][j];
}
}
int ret = f[rows-1][cols-1];
for (int i = 0; i < rows; i++)
free(f[i]);
free(f);
return ret;
}
///
///
/// Approach 2: Dynamic Programming, optimization space
int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obstacleGridColSize){
if (NULL == obstacleGrid || NULL == obstacleGridColSize || \
*obstacleGridColSize < 1 ||obstacleGridSize < 1 || obstacleGrid[0][0])
return 0;
int rows = obstacleGridSize;
int cols = *obstacleGridColSize;
int *f = (int *)calloc(cols, sizeof(int));
f[0] = 1;
for (int i = 0; i < rows; i++) {
// 初始化每一行第一个元素
f[0] = obstacleGrid[i][0] ? 0 : f[0]; //若是障碍则为0,否则等于上一个
for (int j = 1; j < cols; j++)
f[j] = obstacleGrid[i][j] ? 0 : f[j] + f[j-1];
}
int ret = f[cols-1];
free(f);
return ret;
}
///
///
/// Approach 3: Depth First Search (DFS) Algorithm
static inline int dfs(int **obstacleGrid, int **f, int x, int y) {
if (x < 0 || y < 0) return 0;
if (obstacleGrid[x][y]) return 0;
if (x == 0 && y == 0) return f[0][0];
if (f[x][y]) {
return f[x][y];
} else {
f[x][y] = dfs(obstacleGrid, f, x-1, y) + dfs(obstacleGrid, f, x, y-1);
return f[x][y];
}
}
int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obstacleGridColSize){
if (NULL == obstacleGrid || NULL == obstacleGridColSize || \
*obstacleGridColSize < 1 ||obstacleGridSize < 1 || obstacleGrid[0][0])
return 0;
int rows = obstacleGridSize;
int cols = *obstacleGridColSize;
int **f = (int **)calloc(rows, sizeof(int *));
for (int i = 0; i < rows; i++)
f[i] = (int *)calloc(cols, sizeof(int));
f[0][0] = 1;
int ret = dfs(obstacleGrid, f, rows-1, cols-1);
for (int i = 0; i < rows; i++)
free(f[i]);
free(f);
return ret;
}