方法1: 这个很自然第一个想到的肯定是backtracking/dfs。我一开始是想就套用backtracking模版来写的,但是好像不是特别合适,感觉直接dfs就可以了。但是一定要用那个backtracking模版来做的话也可以,可以看下这个链接。下面我直接展示dfs的做法。时间复杂mn,空间复杂mn。
class Solution {
int m;
int n;
Map<Pair<Integer, Integer>, Integer> map = new HashMap<>();
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
this.m = obstacleGrid.length;
this.n = obstacleGrid[0].length;
return backtracking(obstacleGrid, new Pair<>(0,0));
}
public int backtracking(int[][] obstacleGrid, Pair<Integer, Integer> start){
if(map.containsKey(start)) return map.get(start);
int row = start.getKey();
int col = start.getValue();
if(row >= m || col >= n || obstacleGrid[row][col] == 1) return 0;
if(row == m - 1 && col == n - 1) return 1;
int res = backtracking(obstacleGrid, new Pair<>(row + 1, col)) + backtracking(obstacleGrid, new Pair<>(row, col + 1));
map.put(start, res);
return res;
}
}
方法2: dp,时间复杂mn,空间复杂mn。dp的思路完全和62题一模一样,只是遇到阻碍的时候dp数组直接设置为0。当然我们也可以把空间复杂降为1,不新建dp数组,直接在原数组上修改数字就行。具体思路参考lc官方解答。
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int[][] dp = new int[m + 1][n + 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{
if(i == 1 && j == 1) dp[i][j] = 1;
else dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m][n];
}
}