從左上角走到右下角的走法數量(中間有障礙)
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 as1and0respectively 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 is2.
Note: m and n will be at most 100.
package leetcode;
public class Unique_paths_ii {
public static void main(String[] args) {
int [][]a = {{0,1,0,0,0},{1,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}};
System.out.println(uniquePathsWithObstacles(a));
}
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; //若起點或者終點有障礙,則結果為0
}
for(int i = 0 ; i < m ; i ++) {
if(obstacleGrid[i][0] == 1) { //若是有障礙則設定為-100
obstacleGrid[i][0] = -100;
}else if(i>=1 && obstacleGrid[i-1][0] == -100){ //若第一列的上方有一個有障礙,則這一列均不能通過,所以全部設定為-100
obstacleGrid[i][0] = -100;
}else {
obstacleGrid[i][0] = 1; //無障礙設定為1,表示可行
}
}
for(int j = 1 ; j < n ; j ++) {
if(obstacleGrid[0][j] == 1){
obstacleGrid[0][j] = -100; //若是有障礙則設定為-100
}else if(j >= 1 &&obstacleGrid[0][j-1] == -100){ //若第一行的左方有一個有障礙,則這一行均不能通過,所以全部設定為-100
obstacleGrid[0][j] = -100;
}else {
obstacleGrid[0][j] = 1; //無障礙設定為1,表示可行
}
}
for(int i = 1 ; i < m ; i ++) {
for(int j = 1 ;j < n ; j ++) {
if(obstacleGrid[i][j] == 1) {
obstacleGrid[i][j] = -100; //若是有障礙則設定為-100
continue;
}else if(obstacleGrid[i-1][j] == -100 && obstacleGrid[i][j-1] == -100) {
obstacleGrid[i][j] = -100; //左方和上方均有障礙,則此位置無法通過,相當於有障礙,設定為-100
}else if(obstacleGrid[i-1][j] == -100 && obstacleGrid[i][j-1] != -100) {
obstacleGrid[i][j] = obstacleGrid[i][j-1]; //上方有障礙,則從左方通過,把左方位置存入的走法數量繼承過來
}else if(obstacleGrid[i-1][j] != -100 && obstacleGrid[i][j-1] == -100) {
obstacleGrid[i][j] = obstacleGrid[i-1][j]; //左方有障礙,則從上方通過,把上方位置存入的走法數量繼承過來
}else {
obstacleGrid[i][j] = obstacleGrid[i-1][j]+obstacleGrid[i][j-1];//左方和上方均無障礙,則此位置可以通過,可以把兩個方向的走法數量相加之後繼承
}
}
}
if(obstacleGrid[m-1][n-1] == -100) { //若最後沒有繼承任何走法則返回為0
return 0;
}else {
return obstacleGrid[m-1][n-1];
}
}
}
//以下是牛客網上的最優解法
/*public class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length; //取得行數
if(m == 0 || obstacleGrid[0][0] == 1) //行數為0,或者起點有障礙,直接返回為0
return 0;
int n = obstacleGrid[0].length; //取得列數
int[][] steps = new int[m][n]; //定義同等大小的二維陣列
steps[0][0] = 1; //此時起點已經排除有障礙的情況,所以直接賦值為1
for(int i=1; i<n; i++){ //對於第一列的元素如果有障礙則為1,否則無障礙就和其上方元素一樣
if(obstacleGrid[0][i] == 1)
steps[0][i] = 0;
else
steps[0][i] = steps[0][i-1];
}
for(int i=1; i<m; i++){ //對於第一行的元素如果有障礙則為1,否則無障礙就和其左方元素一樣
if(obstacleGrid[i][0] == 1)
steps[i][0] = 0;
else
steps[i][0] = steps[i-1][0];
}
for(int i=1; i<m; i++){
for(int j=1; j<n; j++){
if(obstacleGrid[i][j] == 1) //此處有障礙,則賦值為0,表示到此位置的走法數目為0
steps[i][j] = 0;
else
steps[i][j] = steps[i-1][j] + steps[i][j-1]; //此處無障礙,則是其左方和上方的走法數目的和
}
}
return steps[m-1][n-1]; //最後返回
}
}
*/