Shortest Distance from All Buildings
Problem Statement
Given a 2D grid g
of size n x n
, where each cell can either contain a 1
(indicating a starting point) or a 0
(indicating an empty space), your task is to calculate the shortest distance from each cell to the nearest cell containing a 1
. The distance between two adjacent cells is considered to be 1
. You need to return a 2D grid dis
of the same size, where dis[i][j]
represents the shortest distance from the cell (i, j)
to the nearest 1
in the original grid.
Explanation of the Code
This Python code accomplishes the task using Breadth-First Search (BFS). Here’s a step-by-step explanation:
1. Function Definition: get_distances(g, vis)
Parameters:
g
: The input 2D grid representing the initial layout of1
s and0
s.vis
: A 2D grid of the same size, initialized to0
s, used to keep track of visited cells during the BFS.
Returns:
- A 2D grid
dis
wheredis[i][j]
holds the shortest distance from the cell(i, j)
to the nearest1
in the gridg
.
- A 2D grid
2. Initialization
n
: The size of the grid (assumingg
is a square grid).dis
: A 2D grid initialized with very large values (n*n
), representing initial distances that will be minimized later.q
: A queue used for BFS traversal.delta_arr
: A list of tuples representing the four possible directions of movement (up, down, left, right).
3. Identify All Starting Points (Cells with 1
)
- The code first traverses the entire grid
g
. - For every cell containing
1
, it marks that cell as visited invis
and adds the cell coordinates(i, j)
along with the initial distance0
to the queueq
.
4. BFS Traversal to Calculate Distances
- The BFS loop runs as long as there are cells in the queue
q
. - For each cell
(i, j)
dequeued, the distanced
is assigned todis[i][j]
. - The loop then considers all four possible neighboring cells
(new_row, new_col)
. - If a neighboring cell has not been visited (i.e.,
vis[new_row][new_col] == 0
), it is marked as visited and added to the queue with an incremented distanced + 1
.
5. Return the Distance Grid
- After BFS completes, the grid
dis
containing the shortest distances is returned.
6. Main Function
- The
main()
function initializes a sample gridg
and a correspondingvis
grid. - It then calls the
get_distances
function to compute the distances and prints both the original gridg
and the computed distance griddis
.
7. Output Example
For the input grid g = [[1, 0, 1], [1, 1, 0], [1, 0, 0]]
, the output dis
will be:
g = [[1, 0, 1], [1, 1, 0], [1, 0, 0]]
dis = [[0, 1, 0], [0, 0, 1], [0, 1, 2]]
This indicates that each cell in dis
contains the shortest distance to the nearest 1
in the original grid g
.
def get_distances(g, vis):
n = len(g)
dis = [[n*n for _ in range(n)] for _ in range(n)]
q = []
delta_arr = [(1, 0), (-1, 0), (0, 1), (0, -1)]
# [init] traverse through the graph and identify every 1
for i in range(n):
for j in range(n):
ele = g[i][j]
if ele == 1:
vis[i][j] = 1
q.append((i, j, 0))
# get the other distances using BFS
while q:
i, j, d = q.pop(0)
dis[i][j] = d
for delta in delta_arr:
new_row = i + delta[0]
new_col = j + delta[1]
if -1 < new_col < n and -1 < new_row < n and vis[new_row][new_col] == 0:
vis[new_row][new_col] = 1
q.append((new_row, new_col, d + 1))
return dis
def main():
g = [[1, 0, 1], [1, 1, 0], [1, 0, 0]]
n = len(g)
vis = [[0 for _ in range(n)] for _ in range(n) ]
dis = get_distances(g, vis)
print("g =", g)
print("dis =", dis)
if __name__ == "__main__":
main()
Step-by-Step Code Breakdown
Initialization:
- Define the grid size
n
. - Create the
dis
grid initialized ton*n
. - Initialize an empty queue
q
and define the possible movement directions indelta_arr
.
- Define the grid size
Identify All
1
s in the Grid:- Traverse the grid
g
. - For each
1
, mark the corresponding cell invis
as visited and add it to the queue with distance0
.
- Traverse the grid
BFS to Calculate Distances:
- While there are items in the queue:
- Dequeue the first item and update its corresponding distance in
dis
. - For each of the four possible directions, calculate the new position.
- If the new position is valid and not visited, mark it as visited, update its distance, and enqueue it.
- Dequeue the first item and update its corresponding distance in
- While there are items in the queue:
Output:
- Return the
dis
grid as the result. - The
main()
function demonstrates how to use this function with an example grid.
- Return the