矩阵BFS,搜索最短距离

Walls and Gates 这题matrix里的点的起始状态只有3个,0:gate, -1:wall和int_max: 待搜索的路线。我一开始的做法是,遍历矩阵,每当碰到一个为0的点,就说了我走到了一个gate上,然后从这个gate开始做BFS,把不等于-1的点的距离如果能更新,就更新了。

看了别人的解以后,感觉自己对BFS的理解还是不够深刻,其实只要是从BFS开始搜,搜到的点,就一定是shortest distance,因此就谈不上更新一步了。所以更好的做法是先把所有的matrix[i][j]等于0的点都放到queue里去。每次进去queue后,先得到当前queue的size,在这个size以内,把我能遍历到的下一个值等于int_max的点,更新为current distance + 1,并且放到下一轮的queue中去。

public class Solution {
    public void wallsAndGates(int[][] rooms) {
        if (rooms == null || rooms.length == 0) {
            return;
        }

        int m = rooms.length, n = rooms[0].length;
        Queue<int[]> queue = new LinkedList<int[]>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (rooms[i][j] == 0) {
                    queue.offer(new int[]{i, j});
                }
            }
        }

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

        int distance = 1;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int l = 0; l < size; l++) {
                int[] pos = queue.poll();
                int i = pos[0], j = pos[1];
                for (int k = 0; k < 4; k++) {
                    int x = i + dx[k];
                    int y = j + dy[k];
                    if (x >= 0 && x < m && y >= 0 && y < n && rooms[x][y] == Integer.MAX_VALUE) {
                        rooms[x][y] = distance;
                        queue.offer(new int[]{x, y});
                    } 
                }                
            }
            distance++;
        }
    }
}

Shortest Distance from All Buildings,建一个class叫Pair,有distace去记录更新每一个building到这个点距离,有visited_times去记录有多少个building曾经visit过这个点。每一次搜到一个grid[i][j]等于1的点,就做一个bfs,在bfs更新pair_grid里的值。最后把pair_grid里面,visited_times等于house number的点的最小的distance给return了。

public class Solution {

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

    public int shortestDistance(int[][] grid) {
        if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) {
            return -1;
        }

        int m = grid.length, n = grid[0].length;
        Pair[][] pair_grid = new Pair[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                pair_grid[i][j] = new Pair();
            }
        }

        int count = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    count++;
                    bfs(pair_grid, grid, i, j, new boolean[m][n]);
                }
            }
        }

        int min = Integer.MAX_VALUE;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0 && pair_grid[i][j].visited == count) {
                    min = Math.min(min, pair_grid[i][j].distance);
                }
            }
        }

        return min == Integer.MAX_VALUE ? -1 : min;
    }

    private void bfs(Pair[][] pair_grid, int[][] grid, int i, int j, boolean[][] visited) {
        Queue<int[]> queue = new LinkedList<int[]>();
        queue.offer(new int[]{i, j});
        int distance = 1;

        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int m = 0; m < size; m++) {
                int[] pos = queue.poll();
                int x = pos[0], y = pos[1];
                for (int k = 0; k < 4; k++) {
                    int x2 = x + dx[k], y2 = y + dy[k];
                    if (x2 >= 0 && x2 < grid.length && y2 >= 0 && y2 < grid[0].length && !visited[x2][y2] && grid[x2][y2] == 0) {
                        visited[x2][y2] = true;
                        pair_grid[x2][y2].distance += distance;
                        pair_grid[x2][y2].visited++;
                        queue.offer(new int[]{x2, y2});
                    }
                }
            }
            distance++;
        }
    }
}

class Pair {
    int distance;
    int visited;

    public Pair() {
        distance = 0;
        visited = 0;
    }
}

results matching ""

    No results matching ""