码迷,mamicode.com
首页 > 其他好文 > 详细

Leetcode: Walls and Gates

时间:2015-12-26 14:55:55      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:

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 value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than 2147483647.
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

实际上就是找每个房间到最近的门的距离,我们从每个门开始,广度优先搜索并记录层数就行了。如果某个房间之前被标记过距离,那就选择这个距离和当前距离中较小的那个。这题要注意剪枝,如果下一步是门或者下一步是墙或者下一步已经访问过了,就不要加入队列中。否则会超时。

 1 public class Solution {
 2     public void wallsAndGates(int[][] rooms) {
 3         if (rooms==null || rooms.length==0 || rooms[0].length==0) return;
 4         int m = rooms.length;
 5         int n = rooms[0].length;
 6         for (int i=0; i<m; i++) {
 7             for (int j=0; j<n; j++) {
 8                 if (rooms[i][j] != 0) continue;
 9                 LinkedList<Integer> queue = new LinkedList<Integer>();
10                 boolean[][] visited = new boolean[m][n];
11                 queue.offer(i*n + j);
12                 visited[i][j] = true;
13                 int pNum = 1;
14                 int cNum = 0;
15                 int level = 0;
16                 while (!queue.isEmpty()) {
17                     int cur = queue.poll();
18                     int row = cur/n;
19                     int col = cur%n;
20                     pNum--;
21                     if (row>0 && rooms[row-1][col]!=0 && rooms[row-1][col]!=-1 && !visited[row-1][col]) {
22                         rooms[row-1][col] = Math.min(rooms[row-1][col], level+1);
23                         queue.offer((row-1)*n+col);
24                         visited[row-1][col] = true;
25                         cNum++;
26                     }
27                     if (row<m-1 && rooms[row+1][col]!=0 && rooms[row+1][col]!=-1 && !visited[row+1][col]) {
28                         rooms[row+1][col] = Math.min(rooms[row+1][col], level+1);
29                         queue.offer((row+1)*n+col);
30                         visited[row+1][col] = true;
31                         cNum++;
32                     }
33                     if (col>0 && rooms[row][col-1]!=0 && rooms[row][col-1]!=-1 && !visited[row][col-1]) {
34                         rooms[row][col-1] = Math.min(rooms[row][col-1], level+1);
35                         queue.offer(row*n+col-1);
36                         visited[row][col-1] = true;
37                         cNum++;
38                     }
39                     if (col<n-1 && rooms[row][col+1]!=0 && rooms[row][col+1]!=-1 && !visited[row][col+1]) {
40                         rooms[row][col+1] = Math.min(rooms[row][col+1], level+1);
41                         queue.offer(row*n+col+1);
42                         visited[row][col+1] = true;
43                         cNum++;
44                     }
45                     if (pNum == 0) {//finish this level
46                         level++;
47                         pNum = cNum;
48                         cNum = 0;
49                     }
50                 }
51             }
52         }
53     }
54 }

BFS 还有一种写法,就是不用pNum, cNum两个variables, 而记录每一次queue的size,然后poll() size那么多次,其实本质是一样的

 1 public class Solution {
 2     public void wallsAndGates(int[][] rooms) {
 3         if(rooms.length == 0) return;
 4         for(int i = 0; i < rooms.length; i++){
 5             for(int j = 0; j < rooms[0].length; j++){
 6                 // 如果遇到一个门,从门开始广度优先搜索,标记连通的节点到自己的距离
 7                 if(rooms[i][j] == 0) bfs(rooms, i, j);
 8             }
 9         }
10     }
11     
12     public void bfs(int[][] rooms, int i, int j){
13         Queue<Integer> queue = new LinkedList<Integer>();
14         queue.offer(i * rooms[0].length + j);
15         int dist = 0;
16         // 用一个集合记录已经访问过的点
17         Set<Integer> visited = new HashSet<Integer>();
18         visited.add(i * rooms[0].length + j);
19         while(!queue.isEmpty()){
20             int size = queue.size();
21             // 记录深度的搜索
22             for(int k = 0; k < size; k++){
23                 Integer curr = queue.poll();
24                 int row = curr / rooms[0].length;
25                 int col = curr % rooms[0].length;
26                 // 选取之前标记的值和当前的距离的较小值
27                 rooms[row][col] = Math.min(rooms[row][col], dist);
28                 int up = (row - 1) * rooms[0].length + col;
29                 int down = (row + 1) * rooms[0].length + col;
30                 int left = row * rooms[0].length + col - 1;
31                 int right = row * rooms[0].length + col + 1;
32                 if(row > 0 && rooms[row - 1][col] > 0 && !visited.contains(up)){
33                     queue.offer(up);
34                     visited.add(up);
35                 }
36                 if(col > 0 && rooms[row][col - 1] > 0 && !visited.contains(left)){
37                     queue.offer(left);
38                     visited.add(left);
39                 }
40                 if(row < rooms.length - 1 && rooms[row + 1][col] > 0 && !visited.contains(down)){
41                     queue.offer(down);
42                     visited.add(down);
43                 }
44                 if(col < rooms[0].length - 1 && rooms[row][col + 1] > 0 && !visited.contains(right)){
45                     queue.offer(right);
46                     visited.add(right);
47                 }
48             }
49             dist++;
50         }
51     }
52 }

 

Leetcode: Walls and Gates

标签:

原文地址:http://www.cnblogs.com/EdwardLiu/p/5077950.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!