题目(LeetCode #490)
由空地(用 0
表示)和墙(用 1
表示)组成的迷宫 maze
中有一个球。球可以途经空地向 上、下、左、右 四个方向滚动,且在遇到墙壁前不会停止滚动。当球停下时,可以选择向下一个方向滚动。
给你一个大小为 m x n
的迷宫 maze
,以及球的初始位置 start
和目的地 destination
,其中 start = [startrow, startcol] 且 destination = [destinationrow, destinationcol] 。请你判断球能否在目的地停下:如果可以,返回 true
;否则,返回 false
。
你可以 假定迷宫的边缘都是墙壁(参考示例)。
示例1:
输入:maze = [[0,0,1,0,0],[0,0,0,0,0],[0,0,0,1,0],[1,1,0,1,1],[0,0,0,0,0]], start = [0,4], destination = [4,4]
输出:true
解释:一种可能的路径是 : 左 -> 下 -> 左 -> 下 -> 右 -> 下 -> 右。
示例2:
输入:maze = [[0,0,1,0,0],[0,0,0,0,0],[0,0,0,1,0],[1,1,0,1,1],[0,0,0,0,0]], start = [0,4], destination = [3,2]
输出:false
解释:不存在能够使球停在目的地的路径。注意,球可以经过目的地,但无法在那里停驻。
示例3:
输入:maze = [[0,0,0,0,0],[1,1,0,0,1],[0,0,0,0,0],[0,1,0,0,1],[0,1,0,0,0]], start = [4,3], destination = [0,1]
输出:false
提示:
m == maze.length
n == maze[i].length
1 <= m, n <= 100
maze[i][j]
is 0
or 1
start.length == 2
destination.length == 2
- 0 <= startrow, destinationrow <= m
- 0 <= startcol, destinationcol <= n
- 球和目的地都在空地上,且初始时它们不在同一位置
- 迷宫 至少包括 2 块空地
题解
本题可采用 BFS
或 DFS
求解,与岛屿问题不同的是,小球只有在碰到墙壁时才能停止并更改方向。
BFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class Solution { public boolean hasPath(int[][] maze, int[] start, int[] destination) { if (maze == null || maze.length == 0 || maze[0].length == 0) return false;
int m = maze.length, n = maze[0].length;
Deque<int[]> queue = new ArrayDeque<>(); queue.add(start);
while (!queue.isEmpty()) { int[] cur = queue.poll(); int i = cur[0], j = cur[1];
if (maze[i][j] == 2) continue; if (i == destination[0] && j == destination[1]) return true; maze[i][j] = 2;
int l = j - 1, r = j + 1, u = i - 1, d = i + 1; while (l >= 0 && maze[i][l] != 1) l--; if (maze[i][l + 1] != 2) queue.add(new int[]{i, l + 1});
while (r < n && maze[i][r] != 1) r++; if (maze[i][r - 1] != 2) queue.add(new int[]{i, r - 1});
while (u >= 0 && maze[u][j] != 1) u--; if (maze[u + 1][j] != 2) queue.add(new int[]{u + 1, j});
while (d < m && maze[d][j] != 1) d++; if (maze[d - 1][j] != 2) queue.add(new int[]{d - 1, j}); }
return false; } }
|
DFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class Solution {
int[][] maze; int[] destination; int m, n;
public boolean hasPath(int[][] maze, int[] start, int[] destination) { if (maze == null || maze.length == 0 || maze[0].length == 0) return false;
this.maze = maze; this.destination = destination; m = maze.length; n = maze[0].length;
return dfs(start[0], start[1]); }
private boolean dfs(int i, int j) { if (i < 0 || i >= m || j < 0 || j >= n || maze[i][j] != 0) return false;
if (i == destination[0] && j == destination[1]) return true;
maze[i][j] = 2; int l = j - 1, r = j + 1, u = i - 1, d = i + 1; while (l >= 0 && maze[i][l] != 1) l--; if (dfs(i, l + 1)) return true;
while (r < n && maze[i][r] != 1) r++; if (dfs(i, r - 1)) return true;
while (u >= 0 && maze[u][j] != 1) u--; if (dfs(u + 1, j)) return true;
while (d < m && maze[d][j] != 1) d++; if (dfs(d - 1, j)) return true;
return false; } }
|