迷宫
难度:
标签:
题目描述
代码结果
运行时间: 42 ms, 内存: 17.2 MB
/*
题目思路:
我们可以使用Java Stream API进行DFS的实现。这里的思路是创建一个流来处理迷宫中的每一个点,
使用递归方法来进行DFS搜索。
*/
import java.util.stream.Stream;
import java.util.function.IntPredicate;
public class MazeStream {
private static final int[] DIRS = {-1, 0, 1, 0, -1}; // 用于上下左右移动的方向数组
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
if (maze == null || maze.length == 0 || maze[0].length == 0) return false;
boolean[][] visited = new boolean[maze.length][maze[0].length];
return dfs(maze, start, destination, visited);
}
private boolean dfs(int[][] maze, int[] start, int[] destination, boolean[][] visited) {
if (visited[start[0]][start[1]]) return false;
if (start[0] == destination[0] && start[1] == destination[1]) return true;
visited[start[0]][start[1]] = true;
return Stream.of(0, 1, 2, 3).anyMatch(dir -> {
int x = start[0];
int y = start[1];
while (x >= 0 && x < maze.length && y >= 0 && y < maze[0].length && maze[x][y] == 0) {
x += DIRS[dir];
y += DIRS[dir + 1];
}
x -= DIRS[dir];
y -= DIRS[dir + 1];
return dfs(maze, new int[]{x, y}, destination, visited);
});
}
}
解释
方法:
这个题解使用深度优先搜索(DFS)来判断从起点是否能到达终点。具体来说,从起点开始,沿着四个方向(上下左右)一直滚动,直到撞到墙或者到达边界。每个位置只访问一次,如果滚动到终点则返回 true,否则继续尝试其他方向。如果所有方向都尝试过仍无法到达终点,则返回 false。
时间复杂度:
O(mn * max(m, n))
空间复杂度:
O(mn)
代码细节讲解
🦆
在DFS中,为什么选择一直滚动直到撞墙或出界,而不是每次只移动一步?这种滚动方式对解题有什么特殊的优势吗?
▷🦆
在DFS递归中,当到达一个新位置且未被访问时,如果递归调用返回true,为何可以立即断定整个DFS返回true?这里是否有潜在的回溯机制被省略?
▷🦆
该算法是否考虑了所有可能的边界情况,例如迷宫中的所有位置都是墙壁,或起点和终点位置相同的情况?
▷🦆
在实际的DFS实现中,每次滚动停止后,你检查的是`new_i + dx`和`new_j + dy`,这一步是否可能导致对边界的错误判断?
▷