基础解法
public static int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
if (obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1)
return 0;
int[][] retMatrix = new int[m][n];
// 第一列=1
int ii = 0;
for (; ii < m; ii++)
{
if (obstacleGrid[ii][0] == 0)
retMatrix[ii][0] = 1;
else
break;
}
for (int t = ii; t < m; t++)
retMatrix[t][0] = -1;
// 第一行=1
int jj = 0;
for (; jj < n; jj++)
{
if (obstacleGrid[0][jj] == 0)
retMatrix[0][jj] = 1;
else
break;
}
for (int t = jj; t < n; t++)
retMatrix[0][t] = -1;
for (int i = 1; i < m; i++)
for (int j = 1; j < n; j++)
{
// 本身有障碍
if (obstacleGrid[i][j] == 1)
retMatrix[i][j] = -1;
// 上侧和左侧都有障碍, 本身也是不可达的
else if (retMatrix[i-1][j] == -1 && retMatrix[i][j-1] == -1)
retMatrix[i][j] = -1;
// 上侧有障碍
else if (retMatrix[i-1][j] == -1)
retMatrix[i][j] = retMatrix[i][j-1];
// 左侧有障碍
else if (retMatrix[i][j-1] == -1)
retMatrix[i][j] = retMatrix[i-1][j];
// 上侧和左侧都没有障碍
else
retMatrix[i][j] = retMatrix[i-1][j] + retMatrix[i][j-1];
}
if (retMatrix[m-1][n-1] == -1)
return 0;
return retMatrix[m-1][n-1] ;
}
优化解法(滚动数组)
按行滚动
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int n = obstacleGrid.length;
int m = obstacleGrid[0].length;
int[] f = new int[m]; // 列数
f[0] = obstacleGrid[0][0] == 0 ? 1 : 0;
for (int i = 0; i < n; ++i) { // 行
for (int j = 0; j < m; ++j) { // 列
if (obstacleGrid[i][j] == 1) {
f[j] = 0;
continue;
}
if (j - 1 >= 0 && obstacleGrid[i][j - 1] == 0) {
f[j] = f[j - 1] + f[j]; // 关键步骤:其中, f[j]表示上侧的, f[j-1]表示左侧的
}
}
}
return f[m - 1];
}