学号:16340008
题目: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区块内部的元素,距离0越远,相应数字也越大。同时,相邻两个元素的大小差距不会大于1。因此我们可以从0区块开始,往非0区块收敛,逐层往非0区块中心按数字顺序填充。我们需要先将所有的1替换成另外一种标识,以区分已填充与未填充。实际上使用一个新的矩阵进行填充是更好的。我们可以将未填充的部分标记为无穷大。
于是我们先初始化一个等宽高的矩阵,其所有元素均为无穷大:
row = len(matrix)
col = len(matrix[0])
newMatrix = [[float('inf') for i in range(col)] for i in range(row)]
然后进行宽度优先搜索(因为是一层层往非0区内部搜索)。宽度优先搜索我们可以使用队列,对队列头进行搜索,搜索结果加入队列尾。对于宽度优先搜索的第一层,应是所有0元素的坐标,因为我们是从0开始往非0区深入的。于是我们可以遍历原矩阵,将0元素的坐标推进队列,同时将将要返回的数组对应0区赋值为0
queue = collections.deque()
for i in range(row):
for j in range(col):
if matrix[i][j] == 0:
newMatrix[i][j] = 0
queue.append((i,j))
然后我们只需要循环推出队头,搜索推出的节点周围有没有应当比自己大的元素,有则赋值为该节点的+1,并推进队尾。
while queue:
(r, c) = queue.popleft()
for (move0, move1) in [(1,0), (-1, 0), (0, 1), (0, -1)]:
newR, newC = r + move0, c + move1
if 0 <= newR < row and 0 <= newC < col and newMatrix[r][c] + 1 < newMatrix[newR][newC]:
newMatrix[newR][newC] = newMatrix[r][c] + 1
queue.append((newR, newC))
最后返回新矩阵即可。
以下为完整代码(喊本地测试代码):
import collections
class Solution:
def updateMatrix(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[List[int]]
"""
row = len(matrix)
col = len(matrix[0])
newMatrix = [[float('inf') for i in range(col)] for i in range(row)]
queue = collections.deque()
for i in range(row):
for j in range(col):
if matrix[i][j] == 0:
newMatrix[i][j] = 0
queue.append((i,j))
while queue:
(r, c) = queue.popleft()
for (move0, move1) in [(1,0), (-1, 0), (0, 1), (0, -1)]:
newR, newC = r + move0, c + move1
if 0 <= newR < row and 0 <= newC < col and newMatrix[r][c] + 1 < newMatrix[newR][newC]:
newMatrix[newR][newC] = newMatrix[r][c] + 1
queue.append((newR, newC))
return newMatrix
matrix = [[1, 0, 1, 1, 0, 0, 1, 0, 0, 1], [0, 1, 1, 0, 1, 0, 1, 0, 1, 1], [0, 0, 1, 0, 1, 0, 0, 1, 0, 0], [1, 0, 1, 0, 1, 1, 1, 1, 1, 1], [0, 1, 0, 1, 1, 0, 0, 0, 0, 1], [0, 0, 1, 0, 1, 1, 1, 0, 1, 0], [0, 1, 0, 1, 0, 1, 0, 0, 1, 1], [1, 0, 0, 0, 1, 1, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 0, 1, 0], [1, 1, 1, 1, 0, 1, 0, 0, 1, 1]]
test = Solution()
print(test.updateMatrix(matrix))
Leetcode提交结果:
算法本质是宽度优先搜索,算法时间复杂度为O(n),n为矩阵总元素数(即长×宽)。