问题描述
在一个二维数组迷宫中,机器人从左上角出发,每次只能向右或者向下;判断是否能到达最右下角;若可以,返回其中一条可行的路径。
网格中的障碍物和空位置分别用 1 和 0 来表示。

动态规划思考
dp[][] 数组的含义:该点可不可达。
转移方程的思考:

对于第一行与第一列:只要自己没有障碍物,就认为可达,同时如果有,直接break跳出,因为这两条特殊的路径 只能由前一个点走到,如果某个点有障碍物,后面的所有点也不可达了。
其他格子 只需要其上 或 其右 有一个格子能到达,同时自己又没有障碍物,就可以达。
路径结果输出:我们从结果倒推到原点。打印一条路径。(为什么是从后往前? 因为 如果从出发点往后,我们并不能确保当前可达的点最终能不能到达终点,得考虑更多,所以我们从终点向前推,因为起点是一定可以到达的)

public List<List<Integer>> pathWithObstacles(int[][] obstacleGrid) {
int row = obstacleGrid.length;
int column = obstacle[0].length;
boolean[][] dp = new int[row][column];
List<List<integer>> res = new ArrayList<>();

//如果迷宫为空,那么返回值就为空
if(obstacleGrid == null) return null;

//如果起点和终点有障碍物,那是不可达的
if(obstacleGrid[0][0] == 1 || obstacleGrid[0][0] = 1)
    return res;

dp[0][0] = true;
//第一行
for(int i=1;i<column;i++){
    if(obstacleGrid[0][i] == 0){
        dp[0][i] = true;
    }else{
        break;
    }
}
//第一列
for(int i=1;i<row;i++){
    if(obstacleGrid[i][0] == 0){
        dp[i][0] = true;
    }else{
        break;
    }
}
//其余格子
for(int i=1;i<row;i++)
    for(int j=1;j<column;j++){
        //上边或者左右有一个可达 同时 自己又不存在障碍物,就可达
        if( (dp[i-1][j] || dp[i][j-1]) && obstacleGrid[i][j]==0){
            dp[i][j] = true;
        }
    }
//从终点进行反推
int x = row-1;
int y = column-1;
while(x!=0 || y!=0){   //
    if(x-1>0 && dp[x-1][y]){
        x = x-1;
    }else if(y-1>0 && dp[x][y-1]{   //这个地方用else if,因为其上点 和其右点 选择一个,因为只需要找到一条路径
        y = y-1;
    }
    res.add( Arrays.asList(x,y));
}
Collections.reverse(res);
return res; 

}