图-最短路径-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]]; }