图-最短路径-BFS-788. 迷宫II
2020-04-04 14:14:22
问题描述:
在迷宫中有一个球,里面有空的空间和墙壁。球可以通过滚上,下,左或右移动,但它不会停止滚动直到撞到墙上。当球停止时,它可以选择下一个方向。
给定球的起始位置,目标和迷宫,找到最短距离的球在终点停留。距离是由球从起始位置(被排除)到目的地(包括)所走过的空空间的数量来定义的。如果球不能停在目的地,返回-1。
迷宫由二维数组表示。1表示墙和0表示空的空间。你可以假设迷宫的边界都是墙。开始和目标坐标用行和列索引表示。
样例
Example 1: Input: (rowStart, colStart) = (0,4) (rowDest, colDest)= (4,4) 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 Output: 12 Explanation: (0,4)->(0,3)->(1,3)->(1,2)->(1,1)->(1,0)->(2,0)->(2,1)->(2,2)->(3,2)->(4,2)->(4,3)->(4,4)
注意事项
1.在迷宫中只有一个球和一个目的地。
2.球和目的地都存在于一个空的空间中,它们最初不会处于相同的位置。
3.给定的迷宫不包含边框(比如图片中的红色矩形),但是你可以假设迷宫的边界都是墙。
4.迷宫中至少有2个空的空间,迷宫的宽度和高度都不会超过100。
问题求解:
由于每次扩展的路径长度不等,所以无法采用navie的bfs,但是我们依然可以使用bfs来进行解空间的遍历得到最短路径,本题就是采用bfs来搜索得到最优解。
int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
public int shortestDistance(int[][] maze, int[] start, int[] destination) {
int m = maze.length;
int n = maze[0].length;
int[][] res = new int[m][n];
for (int i = 0; i < m; i++) Arrays.fill(res[i], Integer.MAX_VALUE);
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{start[0], start[1], 0});
while (!q.isEmpty()) {
int[] curr = q.poll();
int x = curr[0];
int y = curr[1];
int w = curr[2];
if (w >= res[x][y]) continue;
res[x][y] = w;
for (int[] dir : dirs) {
int nx = x + dir[0];
int ny = y + dir[1];
int nw = w + 1;
while (nx >= 0 && nx < m && ny >= 0 && ny < n && maze[nx][ny] != 1) {
nx += dir[0];
ny += dir[1];
nw++;
}
nx -= dir[0];
ny -= dir[1];
nw--;
q.add(new int[]{nx, ny, nw});
}
}
return res[destination[0]][destination[1]] == Integer.MAX_VALUE ? -1 : res[destination[0]][destination[1]];
}

浙公网安备 33010602011771号