Question
You are given a m x n 2D grid initialized with these three possible values.
-1
- A wall or an obstacle.0
- A gate.INF
- Infinity means an empty room. We use the value231 - 1 = 2147483647
to representINF
as you may assume that the distance to a gate is less than2147483647
.
Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF
.
For example, given the 2D grid:
INF -1 0 INF INF INF INF -1 INF -1 INF -1 0 -1 INF INF
After running your function, the 2D grid should be:
3 -1 0 1 2 2 1 -1 1 -1 2 -1 0 -1 3 4
Solution
Problems like "shortest distance/ nearest neighbor" can be always solved by BFS.
distance from a specific point (x, y) to one exit (x', y') = distance from (x', y') to (x, y)
So we start BFS on exit points.
Af first, I tried BFS on every exit point one by one, but the time consuming is huge and reports "Time Limit Exceed".
One key point is that we can add all exit points at first, and do BFS once. Time complexity O(mn).
For BFS, don't forget visited[][] array.
1 public class Solution { 2 private final int[][] directions = {{0,1},{0,-1},{1,0},{-1,0}}; 3 4 public void wallsAndGates(int[][] rooms) { 5 if (rooms == null || rooms.length < 1) { 6 return; 7 } 8 int m = rooms.length, n = rooms[0].length; 9 int distance = 0; 10 Deque<int[]> queue = new LinkedList<int[]>(); 11 boolean[][] visited = new boolean[m][n]; 12 // Add all exit points to queue 13 for (int i = 0; i < m; i++) { 14 for (int j = 0; j < n; j++) { 15 if (rooms[i][j] == 0) { 16 queue.add(new int[]{i, j}); 17 } 18 } 19 } 20 // BFS 21 while (!queue.isEmpty()) { 22 distance++; 23 int size = queue.size(); 24 for (int i = 0; i < size; i++) { 25 int[] prev = queue.poll(); 26 for (int k = 0; k < 4; k++) { 27 int newX = prev[0] + directions[k][0]; 28 int newY = prev[1] + directions[k][1]; 29 if (newX < 0 || newX >= rooms.length || newY < 0 || newY >= rooms[0].length) { 30 continue; 31 } 32 if (rooms[newX][newY] == -1) { 33 continue; 34 } 35 // !!! check visisted 36 if (visited[newX][newY]) { 37 continue; 38 } 39 visited[newX][newY] = true; 40 if (rooms[newX][newY] > distance) { 41 rooms[newX][newY] = distance; 42 } 43 queue.offer(new int[]{newX, newY}); 44 } 45 } 46 } 47 } 48 }