Problem

There is aballin a maze with empty spaces and walls. The ball can go through empty spaces by rollingup,down,leftorright, but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction.

Given the ball'sstart position, thedestinationand themaze, determine whether the ball could stop at the destination.

The maze is represented by a binary 2D array. 1 means the wall and 0 means the empty space. You may assume that the borders of the maze are all walls. The start and destination coordinates are represented by row and column indexes.

Example 1

Input 1: a maze represented by a 2D array

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

Input 2: start coordinate (rowStart, colStart) = (0, 4)
Input 3: destination coordinate (rowDest, colDest) = (4, 4)

Output: true
Explanation: One possible way is : left -> down -> left -> down -> right -> down -> right.
Example 2
Input 1: a maze represented by a 2D array

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

Input 2: start coordinate (rowStart, colStart) = (0, 4)
Input 3: destination coordinate (rowDest, colDest) = (3, 2)

Output: false
Explanation: There is no way for the ball to stop at the destination.

思路一(dfs)

写法一
  • 四个方向, 每次都碰到壁再继续下去, 没有结束条件, 所以需要用一个visited数组记录碰到的点
    public boolean hasPath(int[][] maze, int[] start, int[] destination) {
        boolean[][][] visited = new boolean[maze.length][maze[0].length][4];
        return dfs(maze, start[0], start[1], destination, visited, 0)
            || dfs(maze, start[0], start[1], destination, visited, 1)
            || dfs(maze, start[0], start[1], destination, visited, 2)
            || dfs(maze, start[0], start[1], destination, visited, 3);
    }

    int[] dx = {1, -1, 0, 0};
    int[] dy = {0, 0, 1, -1};

    private boolean dfs(int[][] maze, int x, int y, int[] destination, boolean[][][] visited, int dir) {
        if (x == destination[0] && y == destination[1]) return true;
        if (visited[x][y][dir]) return false;

        visited[x][y][dir] = true;
        while (x >=0 && y >= 0 && x < maze.length && y < maze[0].length && maze[x][y] == 0) {
            x += dx[dir];
            y += dy[dir];
        }
        x -= dx[dir];
        y -= dy[dir];

        return dfs(maze, x, y, destination, visited, 0)
            || dfs(maze, x, y, destination, visited, 1)
            || dfs(maze, x, y, destination, visited, 2)
            || dfs(maze, x, y, destination, visited, 3);
    }
写法二
  • visited记录的是每段的起点
    public boolean hasPath(int[][] maze, int[] start, int[] destination) {
        return dfs(maze, start, destination, new boolean[maze.length][maze[0].length]);
    }

    private boolean dfs (int[][] maze, int[] start, int[] destination, boolean[][] visited) {
        if (visited[start[0]][start[1]]) return false;
        if (Arrays.equals(start, destination)) return true;

        visited[start[0]][start[1]] = true;

        for (int i = 0; i < 4; i++) {
            int x = start[0];
            int y = start[1];

            while (x >= 0 && y >= 0 && x < maze.length && y < maze[0].length && maze[x][y] == 0) {
                x += dx[i];
                y += dy[i];

            }

            x -= dx[i];
            y -= dy[i];

            if (dfs(maze, new int[]{x, y}, destination, visited)) return true;
        }
        return false;
    }

    int[] dx = {1, -1, 0, 0};
    int[] dy = {0, 0, 1, -1};

思路二(bfs)

    public boolean hasPath(int[][] maze, int[] start, int[] destination) {
        int m = maze.length;
        int n = maze[0].length;

        int[] dx = {1, -1, 0, 0};
        int[] dy = {0, 0, 1, -1};

        Queue<int[]> queue = new LinkedList<>();
        boolean[][] visited = new boolean[m][n];    
        queue.offer(start);
        visited[start[0]][start[1]] = true;

        while (!queue.isEmpty()) {
            int[] curt = queue.poll();
            if (curt[0] == destination[0] && curt[1] == destination[1]) return true;
            for (int i = 0; i < 4; i++) {
                int x = curt[0];
                int y = curt[1];
                while (canRoll(maze, x + dx[i], y + dy[i])) {
                    x += dx[i];
                    y += dy[i];
                }
                if (visited[x][y]) continue;
                visited[x][y] = true;
                queue.offer(new int[]{x, y});
            }
        }
        return false;
    }

    private boolean canRoll(int[][] maze, int x, int y) {
        if (x >= 0 && x < maze.length && y >= 0 && y < maze[0].length && maze[x][y] == 0) return true;
        return false;
    }

results matching ""

    No results matching ""