题目
https://www.lintcode.com/problem/115
描述
"不同的路径" 的跟进问题:
有一个机器人的位于一个
m×n 个网格左上角。
机器人每一时刻只能向下或者向右移动一步。机器人试图达到网格的右下角。
现在考虑网格中有障碍物,那样将会有多少条不同的路径?
网格中的障碍和空位置分别用 1 和 0 来表示。
最短时间刷“透”算法面试:《66页算法宝典》.pdf
微信添加【jiuzhang15】备注【66】领取
1≤n≤100
1≤m≤100
样例
样例 1:
输入:
obstacleGrid = [[0]]
输出:
1
解释:
只有一个点
样例 2:
输入:
obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:
2
解释:
只有 2 种不同的路径
答案
public class Solution {
/**
* @param obstacleGrid: A list of lists of integers
* @return: An integer
*/
public int uniquePathsWithObstacles(int[][] arr) {
if (arr == null || arr.length == 0) return 0;
int n = arr.length;
int m = arr[0].length;
int[][] dp = new int[n][m];
dp[0][0] = arr[0][0] == 0 ? 1 : 0;
for (int i = 1; i < m; i++) {
if (arr[0][i] == 1) break;
dp[0][i] = dp[0][i - 1];
}
for (int i = 1; i < n; i++) {
if (arr[i][0] == 1) break;
dp[i][0] = dp[i - 1][0];
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
if (arr[i][j] == 1) dp[i][j] = 0;
else {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[n - 1][m - 1];
}
//递归版本,可以做调试实用,提交超时了
public static int uniquePathsWithObstacles1(int[][] obstacleGrid) {
if (obstacleGrid.length == 1 && obstacleGrid[0][0] == 0) return 0;
int[] ans = {0};
dfs(obstacleGrid, 0, 0, ans);
return ans[0];
}
public static void dfs(int[][] arr, int x, int y, int[] ans) {
int n = arr.length, m = arr[0].length;
if (x == n - 1 && y == m - 1) {
ans[0]++;
return;
}
int[][] dirs = {{1, 0}, {0, 1}};
for (int[] dir : dirs) {
int x1 = x + dir[0], y1 = y + dir[1];
if (x1 >= 0 && x1 < n && y1 >= 0 && y1 < m && arr[x1][y1] == 0) {
arr[x1][y1] = 1;
dfs(arr, x1, y1, ans);
arr[x1][y1] = 0;
}
}
}
}