Sunday, February 19, 2017

Build Post Office II

//[TODO]
In this solution, I have made the same mistake as what I made in the last question. While I am iterating through the whole matrix, I should record both the list of HOUSEs and EMPTYs.

class Point {
    public int x;
    public int y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
public class Solution {
    /**
     * @param grid a 2D grid
     * @return an integer
     */
    public int WALL = 2;
    public int HOUSE = 1;
    public int EMPTY = 0;
    public int[] dX = {1, 0, -1, 0};
    public int[] dY = {0, 1, 0, -1};
    public int shortestDistance(int[][] grid) {
        // Write your code here
        int[][] distanceFromHouses = new int[grid.length][grid[0].length];
        int[][] visitedCount = new int[grid.length][grid[0].length];
        ArrayList<Point> houses = new ArrayList<>();
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == HOUSE) {
                    houses.add(new Point(i, j));
                }
            }
        }
        for (Point house : houses) {
            bfs(house, grid, distanceFromHouses, visitedCount);
        }
        int sum = Integer.MAX_VALUE;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == EMPTY) {
                    //System.out.println(visitedCount[i][j] + " " + distanceFromHouses[i][j]);
                    if (visitedCount[i][j] == houses.size()) {
                        sum = Math.min(distanceFromHouses[i][j], sum);
                    }
                }
            }
        }
        if (sum == Integer.MAX_VALUE) {
            return -1;
        } else {
            return sum;
        }
    }
   
    public void bfs(Point start, int[][] grid, int[][] distanceFromHouses, int[][] visitedCount) {
       
        Queue<Point> que = new LinkedList<>();
        que.add(start);
        int distance = 0;
        boolean[][] visited = new boolean[grid.length][grid[0].length];
        while (!que.isEmpty()) {
            distance++;
            int size = que.size();
            for (int k = 0; k < size; k++) {
                Point curr = que.poll();
                //neighbors
                for (int i = 0; i < 4; i++) {
                    int x = curr.x + dX[i];
                    int y = curr.y + dY[i];
                    if (isValid(x, y, grid) && !visited[x][y]) {
                        distanceFromHouses[x][y] += distance;
                        visitedCount[x][y]++;
                        visited[x][y] = true;
                        que.add(new Point(x, y));
                    }
                }
            }
           
        }
    }
   
    public boolean isValid(int x, int y, int[][] grid) {
        if (x < 0 || x >= grid.length) {
            return false;
        }
        if (y < 0 || y >= grid[0].length) {
            return false;
        }
        return grid[x][y] == EMPTY;
    }
   
}

No comments:

Post a Comment