ID | Title | Difficulty | |
---|---|---|---|
Loading... |
317. Shortest Distance from All Buildings
Hard
LeetCode
Array, Breadth-First Search, Matrix
Problem
You are given an m x n grid grid of values 0, 1, or 2, where:
- each 0 marks an empty land that you can pass by freely,
- each 1 marks a building that you cannot pass through, and
- each 2 marks an obstacle that you cannot pass through.
You want to build a house on an empty land that reaches all buildings in the shortest total travel distance. You can only move up, down, left, and right.
Return the shortest travel distance for such a house. If it is not possible to build such a house according to the above rules, return -1.
The total travel distance is the sum of the distances between the houses of the friends and the meeting point.
The distance is calculated using Manhattan Distance, where distance(p1, p2) = | p2.x - p1.x | + | p2.y - p1.y | . |
Example 1:
Input: grid = [[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).
The 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.
Example 2:
Input: grid = [[1,0]]
Output: 1
Example 3:
Input: grid = [[1]]
Output: -1
Code
class Solution {
public int shortestDistance(int[][] grid) {
if (grid == null || grid.length == 0)
return 0;
int m = grid.length;
int n = grid[0].length;
int[][] dist = new int[m][n];
int[][] buildNum = new int[m][n];
int num = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
num++;
helper(grid, dist, buildNum, i, j);
}
}
}
int res = Integer.MAX_VALUE;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][j] == 0 || buildNum[i][j] != num)
continue;
res = Math.min(res, dist[i][j]);
}
}
return res == Integer.MAX_VALUE ? -1 : res;
}
private void helper(int[][] grid, int[][] dist, int[][] buildNum, int row, int col) {
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[] { row, col });
int level = 1;
int[][] dirs = new int[][] { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
boolean[][] visited = new boolean[grid.length][grid[0].length];
visited[row][col] = true;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] curr = queue.poll();
for (int[] dir : dirs) {
int x = curr[0] + dir[0];
int y = curr[1] + dir[1];
if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] != 0 || visited[x][y]) {
continue;
}
queue.offer(new int[] { x, y });
buildNum[x][y] += 1;
visited[x][y] = true;
dist[x][y] += level;
}
}
level++;
}
}
}
按 <- 键看上一题!
316. Remove Duplicate Letters
按 -> 键看下一题!
318. Maximum Product of Word Lengths