This problem involves finding the shortest distance from each empty room to the nearest gate in a grid. The grid contains walls (-1), gates (0), and empty rooms (represented by INF
, a large integer). The solution uses Breadth-First Search (BFS) to efficiently determine these distances.
Approach:
Initialization: We begin by identifying all gate cells (cells with value 0). These cells are added to a queue (q
) for BFS processing. We also initialize a distance variable d
to 0.
BFS Traversal: The core of the algorithm is a BFS traversal. In each iteration of the while loop (while q
):
d
(distance from the gates).len(q)
(or similar in other languages) to ensure that we're only working with cells added in the previous iteration. This is crucial for maintaining the level-order traversal that BFS guarantees.(i, j)
in the queue, we explore its four neighbors (up, down, left, right) using a for
loop and direction array.rooms[x][y] == INF
), we update its distance to the current distance d
(rooms[x][y] = d
) and add it to the queue for processing in the next iteration.In-place Modification: The solution directly modifies the input rooms
array. This is specified by the problem statement.
Time and Space Complexity Analysis:
Time Complexity: O(M * N), where M and N are the dimensions of the grid. Each cell in the grid is visited and processed at most once during the BFS.
Space Complexity: O(M * N) in the worst case. This is because the queue could potentially hold all the cells in the grid if there are no walls or obstacles. In practice, the space used will likely be less than O(M*N) because it's usually less likely all cells are empty rooms that need to be updated.
Code Examples (with explanations):
The provided code in Python, Java, C++, and Go all implement the same BFS algorithm. Let's break down the Python code as an example:
class Solution:
def wallsAndGates(self, rooms: List[List[int]]) -> None:
m, n = len(rooms), len(rooms[0])
inf = 2**31 - 1
q = deque([(i, j) for i in range(m) for j in range(n) if rooms[i][j] == 0]) #Queue initialization - all gates are added.
d = 0
while q:
d += 1
for _ in range(len(q)): #Process all cells added in previous iteration
i, j = q.popleft()
for a, b in [[0, 1], [0, -1], [1, 0], [-1, 0]]: #directions (right,left,down,up)
x, y = i + a, j + b
if 0 <= x < m and 0 <= y < n and rooms[x][y] == inf: #check bounds & empty room
rooms[x][y] = d #update distance
q.append((x, y)) #add to the queue
The other language versions follow the same logic, differing mainly in syntax and data structure implementations (using LinkedList
in Java, queue
in C++, and slices in Go for the queue). The dirs
array (or its equivalent) efficiently handles the exploration of neighboring cells. The use of deque
in Python, and similar queue structures in other languages, optimizes the queue operations for fast enqueue and dequeue.