问题描述:一个骑士从二维网格(M*N)的左上角出发,走到右下角救公主,可以向上、下、左、右四个方向走动每个格点是一个房间,空房间(值为0)可以进入,还有些格点里面有妖怪(值为1)不能进入,每个房间进入后不能重复进入第二次,请问骑士达到目的地有多少种路径并输出所有路劲。
思路:dfs+回溯,从当前位置出发,依次遍历四个方向,每个可抵达的房间(无妖怪)到达后,在每条路劲中进行标记,避免重复进入,该条路劲遍历结束后,该房间恢复访问,遍历所有可行的地图后结束
代码:
public static void main(String[] args) {
int[][] grid = {{0, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}};
System.out.println(uniquePaths(grid));
}
public static List<List<Position>> uniquePaths(int[][] grid) {
List<List<Position>> res = new ArrayList<>();
if (grid[0][0] == 1 || grid[grid.length - 1][grid[0].length - 1] == 1)
return res;
dfs(0, 0, grid, res, new ArrayList<>());
return res;
}
private static void dfs(int x, int y, int[][] grid, List<List<Position>> res, List<Position> current) {
if (x == grid.length -1 && y == grid[0].length -1) {
current.add(new Position(x, y));
res.add(new ArrayList<>(current));
current.remove(current.size() -1);
} else {
grid[x][y] = -1;
current.add(new Position(x, y));
if (x < grid.length -1 && grid[x +1][y] == 0) {
dfs(x + 1, y, grid, res, current);
}
if (x > 0 && grid[x -1][y] == 0) {
dfs(x - 1, y, grid, res, current);
}
if (y > 0 && grid[x][y -1] == 0) {
dfs(x, y - 1, grid, res, current);
}
if (y < grid[0].length -1 && grid[x][y +1] == 0) {
dfs(x, y + 1, grid, res, current);
}
current.remove(current.size() -1);
grid[x][y] = 0;
}
}
static class Position {
int x;
int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
}