542. 01 Matrix

Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.

The distance between two adjacent cells is 1.

Example 1: 
Input:

0 0 0
0 1 0
0 0 0

Output:

0 0 0
0 1 0
0 0 0

 

Example 2: 
Input:

0 0 0
0 1 0
1 1 1

Output:

0 0 0
0 1 0
1 2 1

Note:

  1. The number of elements of the given matrix will not exceed 10,000.
  2. There are at least one 0 in the given matrix.
  3. The cells are adjacent in only four directions: up, down, left and right.

题目含义:给定一个只含0和1的矩阵,找到每个1到0的最短距离。 两个相邻单元格的距离是1 

思路:每一轮以影响值来影响四周的目标值,如果目标值大于影响值+1,则目标值等于影响值+1。用形象的比喻来描述这道题的话,就是一颗石头扔入湖中时,它的影响波及周围,且向四周不断传播它的影响。

第一次更新

对待求矩阵进行一次变换,遇1元素设为最大值,遇0元素要记录row,col值,并放入一个队列中。接下来是求解的核心了,我们只需要寻找到一种机制能够准确更新该数组就可以了。所以该算法的思想,就是首先把这些石头找出来【0元素】,更新规则是,一旦碰到【inf】,我就设一个该【0元素】对【inf】的影响值,此处为1。但由于【0元素】的影响是传递的,所以受它影响的【inf】节点必须得放入队列中,计算下次影响值。

  

第二次更新:以0作为冲击值(因为queue中的元素值都是0)

 

 第二次更新中,[1,1]位置由inf改为1,是被[0,1]位置的0冲刷导致。改为1后,[1,0]和[1,2]位置的0将无法冲刷[1,1]。以[1,0]不能冲刷[1,1]为例,位置[1,1]的值1不满足大于[1,0]的值+1,也就是 [1,1]<=[1,0]+1

 0元素周围的元素均被波及,接下来就是1元素的传递。

 

第三次更新: 以1作为冲击值(因为queue中的元素值都是1)

 第四次更新: 以2作为冲击值(因为queue中的元素值都是2)

 1     public int[][] updateMatrix(int[][] matrix) {
 2 //    一定要看此地址,否则很那理解       http://blog.csdn.net/u014688145/article/details/64126559
 3         int m = matrix.length;
 4         int n = matrix[0].length;
 5         Queue<int[]> q = new LinkedList<>();
 6         for (int i = 0; i < m; i++) {
 7             for (int j = 0; j < n; j++) {
 8                 if (matrix[i][j] == 0) q.add(new int[]{i, j}); //把0元素加入队列中,以备波及影响周围元素
 9                 else matrix[i][j] = Integer.MAX_VALUE;//设为最大值,方便求0元素影响值
10             }
11         }
12         //溅起的涟漪,代表传播的四个方向
13         int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
14         while (!q.isEmpty()) {
15             int[] cell = q.poll();
16             for (int[] dirc : dirs) {
17                 //需要比较的下一位置元素
18                 int r = cell[0] + dirc[0];
19                 int c = cell[1] + dirc[1];
20 
21                 //如果下一位置的元素值,小于等于(当前位置元素值+1),直接跳过
22                 if (r < 0 || r >= m || c < 0 || c >= n || matrix[r][c] <= (matrix[cell[0]][cell[1]] + 1)) continue;
23                 else {
24                     matrix[r][c] = matrix[cell[0]][cell[1]] + 1;
25                     q.offer(new int[]{r, c});
26                 }
27             }
28         }
29         return matrix;        
30     }

 

posted @ 2017-10-24 14:25  daniel456  阅读(184)  评论(0编辑  收藏  举报