Follow up for "Unique Paths":
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.
For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.
[ [0,0,0], [0,1,0], [0,0,0] ]
The total number of unique paths is 2
.
Note: m and n will be at most 100.
public class Solution {
public int uniquePathsWithObstacles (int[][] obstacleGrid) {
//开始应该判断一些 obstacleGrid 是不是为 null 或者为不为空
int row = obstacleGrid.length;
int col = obstacleGrid[0].length;
int[][] map = new int[row][col];
/**
* 记得考虑两种情况
* 1 当要到达的点本身有 obstacle, 则直接返回0
* 2 要记得考虑边界值,即最后一列和最后一行的算法跟其他的不一样
*/
if (obstacleGrid[row - 1][col - 1] == 1){
return 0;
}else {
map[row - 1][col - 1] = 1;
for (int i = col - 2; i >= 0; i--) {
if (obstacleGrid[row-1][i] == 1) {
//其实直接break 就好,因为数组初始化时,每个变量都默认为0了
map[row-1][i] = 0;
}else {
map[row-1][i] = map[row-1][i+1];
}
}
for (int i = row - 2; i >= 0; i--) {
if (obstacleGrid[i][col-1] == 1) {
map[i][col-1] = 0;
}else {
map[i][col-1] = map[i+1][col-1];
}
}
for (int i = row - 2; i >= 0; i--) {
for (int j = col - 2; j >= 0; j--) {
if (obstacleGrid[i][j] == 1) {
map[i][j] = 0;
}else {
map[i][j] = map[i][j+1] + map[i+1][j];
}
}
}
return map[0][0];
}
别人的答案
public class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
if (obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0) {
return 0;
}
int n = obstacleGrid.length;
int m = obstacleGrid[0].length;
int[][] paths = new int[n][m];
for (int i = 0; i < n; i++) {
if (obstacleGrid[i][0] != 1) {
paths[i][0] = 1;
} else {
break;
}
}
for (int i = 0; i < m; i++) {
if (obstacleGrid[0][i] != 1) {
paths[0][i] = 1;
} else {
break;
}
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
if (obstacleGrid[i][j] != 1) {
paths[i][j] = paths[i - 1][j] + paths[i][j - 1];
} else {
paths[i][j] = 0;
}
}
}
return paths[n - 1][m - 1];
}
}
这是第二次写的程序,这里比上面方法效率低的一点是 当初始化第一行和第一列的时候,如果某处obstacleGrid 的点为1, 则result 这个点以后全都为0即可,即直接break 结束循环即可(看上面程序)
public class Solution {
public int uniquePathsWithObstacles (int[][] obstacleGrid) {
if (obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0) {
return 0;
}
int row = obstacleGrid.length;
int col = obstacleGrid[0].length;
int[][] result = new int[row][col];
if (obstacleGrid[0][0] == 1) {
return 0;
}
result[0][0] = 1;
for (int i = 1; i < col; i++) {
result[0][i] = obstacleGrid[0][i] == 1 ? 0 : result[0][i - 1];
}
for (int i = 1; i < row; i++) {
result[i][0] = obstacleGrid[i][0] == 1 ? 0 : result[i - 1][0];
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
result[i][j] = obstacleGrid[i][j] == 1 ? 0 : result[i - 1][j] + result[i][j - 1];
}
}
return result[row - 1][col - 1];
}
}
本来想optimize 的,结果又漏掉corner case
public class Solution {
public int uniquePathsWithObstacles (int[][] obstacleGrid) {
if (obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0) {
return 0;
}
int row = obstacleGrid.length;
int col = obstacleGrid[0].length;
int[][] result = new int[row][col];
for (int i = 0; i < col; i++) {
if (obstacleGrid[0][i] != 1) {
result[0][i] = 1;
} else {
break;
}
}
//for (int i = 1; i < row; i++)
// 如果写成 i 从1 开始,则对于obstacleGrid[0][0] = 1 的这种情况考虑出错
//{{1, 0}} test case return 1,wrong answer
for (int i = 0; i < row; i++) {
if (obstacleGrid[i][0] != 1) {
result[i][0] = 1;
} else {
break;
}
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
result[i][j] = obstacleGrid[i][j] == 1 ? 0 : result[i - 1][j] + result[i][j - 1];
}
}
return result[row - 1][col - 1];
}
}