(待更..)【Leetcode 广搜、动态规划】01 矩阵(542)
题目
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
示例 1:
输入:
0 0 0
0 1 0
0 0 0
输出:
0 0 0
0 1 0
0 0 0
示例 2:
输入:
0 0 0
0 1 0
1 1 1
输出:
0 0 0
0 1 0
1 2 1
注意:
给定矩阵的元素个数不超过 10000。
给定矩阵中至少有一个元素是 0。
矩阵中的元素只在四个方向上相邻: 上、下、左、右。
解答
也是一道搜索题。要找出每个非零数字和最近0的距离,用广度优先搜索很合适,以某个非零数字为起点,检查走一步的范围中是否包含0;若不包含,再检查走两步能到达哪些点,是否包含0;以此类推,直到碰到数字0,返回走过的步数。
1,广度优先搜索bfs,用队列实现。Time: O(mn),Space: O(mn)
2,写完这题又想了想,用深搜dfs也可以,每次从起点dfs找到0,会有多组解,取最小值,深搜过程中book先标记再取消。
3,动态规划,看题解有这个办法,待更..
广度优先搜索代码:
class Queue: # 队列数据结构
def __init__(self):
self.x = 0
self.y = 0
self.distance = 0
class Solution:
def __init__(self):
self.book = []
self.next = [
[0, 1],
[1, 0],
[0, -1],
[-1, 0]
]
self.m = 0
self.n = 0
self.ans = []
self.temp = []
def updateMatrix(self, matrix):
if not matrix:
return []
self.m, self.n = len(matrix), len(matrix[0])
self.ans = [
[0 for _ in range(self.n)] for _ in range(self.m)
]
self.que = [Queue() for _ in range(self.m*self.n+1)]
self.book = [
[0 for _ in range(self.n)] for _ in range(self.m)
]
for i in range(self.m):
for j in range(self.n):
self.temp = [] # 记录本次bfs标记的点,方便book清空复位;book很大的时候,每次都初始化会超时的。。。
if matrix[i][j] == 0:
self.ans[i][j] = 0
else:
head = tail = 1
self.que[tail].x = i
self.que[tail].y = j
self.que[tail].distance = 0
tail += 1
self.book[i][j] = 1
self.temp.append([i, j])
self.ans[i][j] = self.bfs(head, tail, matrix)
for x in self.temp: # book清空复位
self.book[x[0]][x[1]] = 0
return self.ans
def bfs(self, head, tail, matrix):
while head < tail:
for i in range(4):
tx = self.que[head].x + self.next[i][0]
ty = self.que[head].y + self.next[i][1]
if tx >= 0 and ty >= 0 and tx < self.m and ty < self.n and self.book[tx][ty] == 0:
self.que[tail].x = tx
self.que[tail].y = ty
self.que[tail].distance = self.que[head].distance + 1
tail += 1
self.book[tx][ty] = 1
self.temp.append([tx, ty]) # 记录本次bfs标记的点
if matrix[tx][ty] == 0:
return self.que[tail - 1].distance
head += 1
s = Solution()
ans = s.updateMatrix([[0, 0, 0],
[0, 1, 0],
[1, 1, 1]])
import pprint
pprint.pprint(ans)
#[[0, 0, 0],
# [0, 1, 0],
# [1, 2, 1]]