317. Shortest Distance from All Buildings
题目:
You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You can only move up, down, left and right. You are given a 2D grid of values 0, 1 or 2, where:
- Each 0 marks an empty land which you can pass by freely.
- Each 1 marks a building which you cannot pass through.
- Each 2 marks an obstacle which you cannot pass through.
Example:
Input: [[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]] 1 - 0 - 2 - 0 - 1 | | | | | 0 - 0 - 0 - 0 - 0 | | | | | 0 - 0 - 1 - 0 - 0 Output: 7 Explanation: Given three buildings at(0,0)
,(0,4)
,(2,2)
, and an obstacle at(0,2), t
he point(1,2)
is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal. So return 7.
Note:
There will be at least one building. If it is not possible to build such house according to the above rules, return -1.
链接: http://leetcode.com/problems/maximum-product-of-word-lengths/
题解:
给一块空地,求在空地上新盖一座楼,到其他楼的距离最短。这里我们要用到BFS,就是从每个楼开始用BFS计算空地 "0"到这栋楼的距离,最后把每个空地到每栋楼的距离加起来,求一个最小值。这里我们还要算出楼的数目,仅当空地能连接所有楼的时候,我们才愿意在这块空地上造楼。我们也要维护一个visited矩阵来避免重复。
Time Complexity - O(4mn), Space Complexity - O(mn * k), k为1的数目
public class Solution { private final int[][] directions = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; public int shortestDistance(int[][] grid) { if(grid == null || grid.length == 0) { return Integer.MAX_VALUE; } int rowNum = grid.length; int colNum = grid[0].length; int[][] distance = new int[rowNum][colNum]; int[][] canReachBuildings = new int[rowNum][colNum]; int buildingNum = 0; for(int i = 0; i < rowNum; i++) { for(int j = 0; j < colNum; j++) { if(grid[i][j] != 0) { distance[i][j] = Integer.MAX_VALUE; } if(grid[i][j] == 1) { // find out all buildings buildingNum++; updateDistance(grid, distance, canReachBuildings, i, j); } } } int min = Integer.MAX_VALUE; for(int i = 0; i < rowNum; i++) { for(int j = 0; j < colNum; j++) { if(canReachBuildings[i][j] == buildingNum) { min = Math.min(distance[i][j], min); } } } return min == Integer.MAX_VALUE ? -1 : min; } private void updateDistance(int[][] grid, int[][] distance, int[][] canReachBuildings, int row, int col) { Queue<int[]> queue = new LinkedList<>(); queue.offer(new int[]{row, col}); boolean[][] visited = new boolean[grid.length][grid[0].length]; visited[row][col] = true; int dist = 0; int curLevel = 1; int nextLevel = 0; while(!queue.isEmpty()) { int[] position = queue.poll(); distance[position[0]][position[1]] += dist; curLevel--; for(int[] direction : directions) { int x = position[0] + direction[0]; int y = position[1] + direction[1]; if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] != 0) { continue; } if(!visited[x][y]) { queue.offer(new int[]{x, y}); nextLevel++; visited[x][y] = true; canReachBuildings[x][y]++; } } if(curLevel == 0) { curLevel = nextLevel; nextLevel = 0; dist++; } } } }
Reference:
https://leetcode.com/discuss/74453/36-ms-c-solution
https://leetcode.com/discuss/74422/clean-solution-easy-understanding-with-simple-explanation
https://leetcode.com/discuss/74999/java-solution-with-explanation-and-time-complexity-analysis
https://leetcode.com/discuss/74380/my-bfs-java-solution