class Solution {
private int bfs(int[][] grid, int row, int col, int totalHouses) {
// Next four directions.
int dirs[][] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int rows = grid.length;
int cols = grid[0].length;
int distanceSum = 0;
int housesReached = 0;
// Queue to do a bfs, starting from (row, col) cell.
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{ row, col });
// Keep track of visited cells.
boolean[][] vis = new boolean[rows][cols];
vis[row][col] = true;
int steps = 0;
while (!q.isEmpty() && housesReached != totalHouses) {
for (int i = q.size(); i > 0; --i) {
int[] curr = q.poll();
row = curr[0];
col = curr[1];
// If this cell is a house, then add the distance from source to this cell
// and we go past from this cell.
if (grid[row][col] == 1) {
distanceSum += steps;
housesReached++;
continue;
}
// This cell was empty cell, hence traverse the next cells which is not a blockage.
for (int[] dir : dirs) {
int nextRow = row + dir[0];
int nextCol = col + dir[1];
if (nextRow >= 0 && nextCol >= 0 && nextRow < rows && nextCol < cols) {
if (!vis[nextRow][nextCol] && grid[nextRow][nextCol] != 2) {
vis[nextRow][nextCol] = true;
q.offer(new int[]{ nextRow, nextCol });
}
}
}
}
// After traversing one level of cells, increment the steps by 1 to reach to next level.
steps++;
}
// If we did not reach all houses, then any cell visited also cannot reach all houses.
// Set all cells visted to 2 so we do not check them again and return MAX_VALUE.
if (housesReached != totalHouses) {
for (row = 0; row < rows; row++) {
for (col = 0; col < cols; col++) {
if (grid[row][col] == 0 && vis[row][col]) {
grid[row][col] = 2;
}
}
}
return Integer.MAX_VALUE;
}
// If we have reached all houses then return the total distance calculated.
return distanceSum;
}
public int shortestDistance(int[][] grid) {
int minDistance = Integer.MAX_VALUE;
int rows = grid.length;
int cols = grid[0].length;
int totalHouses = 0;
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
if (grid[row][col] == 1) {
totalHouses++;
}
}
}
// Find the min distance sum for each empty cell.
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
if (grid[row][col] == 0) {
minDistance = Math.min(minDistance, bfs(grid, row, col, totalHouses));
}
}
}
// If it is impossible to reach all houses from any empty cell, then return -1.
if (minDistance == Integer.MAX_VALUE) {
return -1;
}
return minDistance;
}
};Where and are the number of rows and columns in
gridrespectively.
class Solution {
private void bfs(int[][] grid, int[][][] distances, int row, int col) {
int dirs[][] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int rows = grid.length;
int cols = grid[0].length;
// Use a queue to do a bfs, starting from each cell located at (row, col).
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{ row, col });
// Keep track of visited cells.
boolean[][] vis = new boolean[rows][cols];
vis[row][col] = true;
int steps = 0;
while (!q.isEmpty()) {
for (int i = q.size(); i > 0; --i) {
int[] curr = q.poll();
row = curr[0];
col = curr[1];
// If we reached an empty cell, then add the distance
// and increment the count of houses reached at this cell.
if (grid[row][col] == 0) {
distances[row][col][0] += steps;
distances[row][col][1] += 1;
}
// Traverse the next cells which is not a blockage.
for (int[] dir : dirs) {
int nextRow = row + dir[0];
int nextCol = col + dir[1];
if (nextRow >= 0 && nextCol >= 0 && nextRow < rows && nextCol < cols) {
if (!vis[nextRow][nextCol] && grid[nextRow][nextCol] == 0) {
vis[nextRow][nextCol] = true;
q.offer(new int[]{ nextRow, nextCol });
}
}
}
}
// After traversing one level cells, increment the steps by 1.
steps++;
}
}
public int shortestDistance(int[][] grid) {
int minDistance = Integer.MAX_VALUE;
int rows = grid.length;
int cols = grid[0].length;
int totalHouses = 0;
// Store { total_dist, houses_count } for each cell.
int[][][] distances = new int[rows][cols][2];
// Count houses and start bfs from each house.
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
if (grid[row][col] == 1) {
totalHouses++;
bfs(grid, distances, row, col);
}
}
}
// Check all empty lands with houses count equal to total houses and find the min ans.
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
if (distances[row][col][1] == totalHouses) {
minDistance = Math.min(minDistance, distances[row][col][0]);
}
}
}
// If we haven't found a valid cell return -1.
if (minDistance == Integer.MAX_VALUE) {
return -1;
}
return minDistance;
}
};Where and are the number of rows and columns in
gridrespectively.
class Solution:
def shortestDistance(self, grid: List[List[int]]) -> int:
# Next four directions.
dirs = [[1, 0], [-1, 0], [0, 1], [0, -1]]
rows = len(grid)
cols = len(grid[0])
# Total Matrix to store total distance sum for each empty cell.
total = [[0] * cols for _ in range(rows)]
empty_land_value = 0
min_dist = float('inf')
for row in range(rows):
for col in range(cols):
# Start a BFS from each house.
if grid[row][col] == 1:
min_dist = float('inf')
# Use a queue to perform a BFS, starting from the cell at (row, col).
q = deque([(row, col)])
steps = 0
while q:
steps += 1
level_size = len(q)
for level in range(level_size):
curr = q.popleft()
for dir in dirs:
next_row = curr[0] + dir[0]
next_col = curr[1] + dir[1]
# For each cell with the value equal to empty land value
# add distance and decrement the cell value by 1.
if (0 <= next_row < rows and
0 <= next_col < cols and
grid[next_row][next_col] == empty_land_value):
grid[next_row][next_col] -= 1
total[next_row][next_col] += steps
q.append((next_row, next_col))
min_dist = min(min_dist, total[next_row][next_col])
# Decrement empty land value to be searched in next iteration.
empty_land_value -= 1
return -1 if min_dist == float('inf') else min_distWhere and are the number of rows and columns in
gridrespectively.