980. 不同路径 III Hard
题目描述:在二维网格 grid 上,有 4 种类型的方格:
- 1 表示起始方格。且只有一个起始方格。
- 2 表示结束方格,且只有一个结束方格。
- 0 表示我们可以走过的空方格。
- -1 表示我们无法跨越的障碍。
返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目,每一个无障碍方格都要通过一次
。
dfs题解:回溯深度优先搜索
尝试遍历每一个 0 方格,并在走过的方格里留下一个障碍。回溯的时候,我们要删除那些自己留下的障碍。
- 和岛屿问题的思路很像
public class Main {
int ans;
int[][] grid;
int[] dr = new int[]{0, -1, 0, 1};
int[] dc = new int[]{1, 0, -1, 0};
int row, col,endx,endy;
public int uniquePathsIII(int[][] grid) {
this.grid = grid;
row = grid.length;
col = grid[0].length;
int todo = 0;
int startx = 0, starty = 0;
for (int r = 0; r < row; ++r)
for (int c = 0; c < col; ++c) {
if (grid[r][c] != -1) {
todo++;
}
if (grid[r][c] == 1) {
startx = r;
starty = c;
} else if (grid[r][c] == 2) {
endx = r;
endy = c;
}
}
ans = 0;
dfs(startx, starty, todo);
return ans;
}
public void dfs(int r, int c, int todo) {
todo--;
if (todo < 0) return;
if (r == endx && c == endy) {
if (todo == 0) ans++;
return;
}
grid[r][c] = 3;
for (int k = 0; k < 4; ++k) {
int nr = r + dr[k];
int nc = c + dc[k];
if (0 <= nr && nr < row && 0 <= nc && nc < col) {
if (grid[nr][nc] % 2 == 0)
dfs(nr, nc, todo);
}
}
grid[r][c] = 0;
}
}
动态规划题解 TODO
62. 不同路径
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for (int i = 0; i < m; i++) {
dp[i][0] = 1;
}
for (int i = 0; i < n; i++) {
dp[0][i] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}
63. 不同路径 II
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int[][] dp = new int[obstacleGrid.length][obstacleGrid[0].length];
for (int i = 0; i < dp.length; i++) {
if (obstacleGrid[i][0] == 1) {
break;
}
dp[i][0] = 1;
}
for (int i = 0; i < dp[0].length; i++) {
if (obstacleGrid[0][i] == 1) {
break;
}
dp[0][i] = 1;
}
for (int i = 1; i < dp.length; i++) {
for (int j = 1; j < dp[0].length; j++) {
if (obstacleGrid[i][j] == 1) {
continue;
}
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[dp.length-1][dp[0].length-1];
}
}