"不同的路径" 的跟进问题:
现在考虑网格中有障碍物,那样将会有多少条不同的路径?
网格中的障碍和空位置分别用 1 和 0 来表示。
样例
如下所示在3x3的网格中有一个障碍物:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
一共有2条不同的路径从左上角到右下角。
注意事项
m 和 n 均不超过100
解题思路:
和Lintcode 114. 不同的路径类似。设dp[i][j]为机器人有多少种方式从左上角走到[i][j]。
public class Solution {
/**
* @param obstacleGrid: A list of lists of integers
* @return: An integer
*/
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
// write your code here
if(obstacleGrid==null || obstacleGrid.length==0 ||obstacleGrid[0].length==0 || obstacleGrid[0][0]==1)
return 0;
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int[][] dp = new int[m][n];
//初始条件
dp[0][0] = 1;
//边界条件
for(int i=1 ; i<m ; i++){
if(obstacleGrid[i][0] == 1)
dp[i][0] = 0;
else
dp[i][0] = dp[i-1][0];
}
for(int j=1 ; j<n ; j++){
if(obstacleGrid[0][j] == 1)
dp[0][j] = 0;
else
dp[0][j] = dp[0][j-1];
}
//状态方程
for(int i=1 ; i<m ; i++){
for(int j=1 ; j<n ; j++){
if(obstacleGrid[i][j] == 1)
dp[i][j] = 0;
else
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}
优化方法:通过在dp数组左上角增加一行和一列用来表示虚拟的边界,这样就不用单独讨论边界条件,代码更简洁。
public class Solution {
/**
* @param obstacleGrid: A list of lists of integers
* @return: An integer
*/
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
// write your code here
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
if(m==0 || n==0)
return 0;
int[][] dp = new int[m+1][n+1];
dp[0][1] = 1;
for(int i=1; i<=m; i++){
for(int j=1; j<=n; j++){
if(obstacleGrid[i-1][j-1] == 1)
dp[i][j] = 0;
else
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m][n];
}
}