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

  

原文地址:https://www.cnblogs.com/hyserendipity/p/12631664.html