給定一個由 0 和 1 組成的矩陣,找出每一個元素到最近的 0 的距離。java
兩個相鄰元素間的距離爲 1 。node
Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.python
The distance between two adjacent cells is 1.數組
示例 1: 輸入:bash
0 0 0
0 1 0
0 0 0
複製代碼
輸出:app
0 0 0
0 1 0
0 0 0
複製代碼
示例 2: 輸入:spa
0 0 0
0 1 0
1 1 1
複製代碼
輸出:rest
0 0 0
0 1 0
1 2 1
複製代碼
注意:code
Note:cdn
關鍵字:最近、距離。那確定是廣度優先搜索。相似以前的文章 島嶼數量: mp.weixin.qq.com/s/BrlMzXTtZ…
將這個問題轉化成圖,那就是求每一個節點 1 到節點 0 最短的路徑是多少。從某個節點開始,上下左右向外擴展,每次擴展一圈距離累加1,如:
輸入:
1 1 1
0 1 0
0 0 0
複製代碼
轉化成圖(Graph),每種顏色表明一個層級:
這就變成了求某個節點到某個節點的深度了。
因此這道題有兩種思路:
兩種方法各有優劣,
以0節點爲根節點解題,要麼開闢一個新的二維數組以記錄路徑,要麼先遍歷一遍將全部的節點1的值改成不可能和路徑大小重複的值。
以1節點爲根節點,那麼就要作一些多餘的重複遍歷。
邏輯順序:
以輸入下列二維數組爲例:
1 1 1
0 1 1
0 0 1
複製代碼
先把原節點值爲1 的節點改成M (路徑值不可能達到的值,該題中大於10000便可)
先侵染0節點附近的M節點,0節點加1以後獲得1節點
再侵染1節點附近的M節點,1節點加1以後獲得2節點
......
Java:
class Solution {
public int[][] updateMatrix(int[][] matrix) {
int row = matrix.length, column = matrix[0].length;
int[][] neighbors = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};//鄰居節點的索引偏移量
Queue<int[]> queue = new LinkedList<>();//隊列
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (matrix[i][j] == 0) queue.offer(new int[]{i, j});
else matrix[i][j] = Integer.MAX_VALUE;//節點值爲1的節點改成一個路徑不可能達到的值
}
}
while (!queue.isEmpty()) {
int[] tmp = queue.poll();
for (int i = 0; i < 4; i++) {
//獲得鄰居節點索引
int x = tmp[0] + neighbors[i][0];
int y = tmp[1] + neighbors[i][1];
if (x >= 0 && x < row && y >= 0 && y < column && matrix[tmp[0]][tmp[1]] < matrix[x][y]) {
matrix[x][y] = matrix[tmp[0]][tmp[1]] + 1;//該節點的值獲得鄰居節點的路徑值+1
queue.offer(new int[]{x, y});
}
}
}
return matrix;
}
}
複製代碼
Python3:
class Solution:
def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
row, column = len(matrix), len(matrix[0])
nerghbors = [(0, 1), (0, -1), (1, 0), (-1, 0)]
queue = collections.deque()
for i in range(row):
for j in range(column):
if matrix[i][j] == 0:
queue.append((i, j))
else:
matrix[i][j] = 10001
while queue:
x, y = queue.popleft()
for i, j in nerghbors:
xx = i + x
yy = j + y
if 0 <= xx < row and 0 <= yy < column and matrix[x][y] < matrix[xx][yy]:
matrix[xx][yy] = matrix[x][y] + 1
queue.append((xx, yy))
return matrix
複製代碼
Java:
class Solution {
public int[][] updateMatrix(int[][] matrix) {
int row = matrix.length, column = matrix[0].length;
for (int i = 0; i < row; i++)
for (int j = 0; j < column; j++)
if (matrix[i][j] == 1) matrix[i][j] = bfs(matrix, i, j, row, column);
return matrix;
}
private int bfs(int[][] matrix, int i, int j, int row, int column) {
int count = 0;
Queue<Integer> queue = new LinkedList<>();
Set<int[]> set = new HashSet<>();
queue.add(i * column + j);//記錄索引的另外一種方法
while (!queue.isEmpty()) {
int size = queue.size();
count += 1;
for (int k = 0; k < size; k++) {
int tmp = queue.poll();
int x = tmp / column, y = tmp % column;//獲得索引座標
//處理上下左右四個鄰居節點,遇到0節點直接返回count路徑值
if (x + 1 < row && !set.contains((x + 1) * column + y)) {
if (matrix[x + 1][y] != 0) queue.add((x + 1) * column + y);
else return count;
}
if (x - 1 >= 0 && !set.contains((x - 1) * column + y)) {
if (matrix[x - 1][y] != 0) queue.add((x - 1) * column + y);
else return count;
}
if (y + 1 < column && !set.contains(x * column + y + 1)) {
if (matrix[x][y + 1] != 0) queue.add(x * column + y + 1);
else return count;
}
if (y - 1 >= 0 && !set.contains(x * column + y - 1)) {
if (matrix[x][y - 1] != 0) queue.add(x * column + y - 1);
else return count;
}
}
}
return count;
}
}
複製代碼
Python3:
class Solution:
def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
row, column = len(matrix), len(matrix[0])
for i in range(row):
for j in range(column):
if matrix[i][j] == 1:
matrix[i][j] = self.bfs(i, j, matrix, row, column)
return matrix
def bfs(self, i: int, j: int, matrix: List[List[int]], row: int, column: int) -> int:
queue = collections.deque()
count = 0
nodeset = set()
queue.append((i, j))
while queue:
size = len(queue)
count += 1
for i in range(size):
x, y = queue.popleft()
if x + 1 < row and (x + 1, y) not in nodeset:
if matrix[x + 1][y] != 0:
queue.append((x + 1, y))
else:
return count
if x - 1 >= 0 and (x - 1, y) not in nodeset:
if matrix[x - 1][y] != 0:
queue.append((x - 1, y))
else:
return count
if y + 1 < column and (x, y + 1) not in nodeset:
if matrix[x][y + 1] != 0:
queue.append((x, y + 1))
else:
return count
if y - 1 >= 0 and (x, y - 1) not in nodeset:
if matrix[x][y - 1] != 0:
queue.append((x, y - 1))
else:
return count
return count
複製代碼
歡迎關注微.信公.衆號:愛寫Bug