第9天 广度优先搜索 / 深度优先搜索
542. 01矩阵
题目含义:距离1最近的0有多远
1、DFS爆搜会超时。即只搜1附近的0,第一层上下左右没有,就搜下一层。注意这里需要记录层数,层数即为距离。
#seen不用数组,而用set存储也行。下面为超时代码:
#BFS爆搜
class Solution(object):
def updateMatrix(self, mat):
"""
:type mat: List[List[int]]
:rtype: List[List[int]]
"""
ans = mat
l = len(mat)
w = len(mat[0])
for i in range(l):
for j in range(w):
if mat[i][j] == 1:
ans[i][j] = 0
queue = []
seen = set()
queue.append([i,j])
seen.add((i,j))
find = False
while not find:
length = len(queue)
for _ in range(length):
k, t = queue.pop(0)
for x,y in ([k-1,t],[k+1,t],[k,t-1],[k,t+1]):
if 0<=x<l and 0<=y<w and (x,y) not in seen:
if mat[x][y] == 0:
find = True
ans[i][j] +=1
break
else:
queue.append([x,y])
seen.add((x,y))
if find:
break
length -= 1
if length == 0:
ans[i][j] +=1
return ans
2、多源BFS。思想:找0附近的1。 0距0本身长度为0,0上下左右一层的1距离0的长度为1,在外层1距离1的距离为1,距离0的距离为2,依此类推。先把所有0入队,逐渐出队的过程中把0周围的1入队,直到队空,所有都遍历完毕。
多源BFS就不像单源BFS一样最初只入队一个结点,而是入对多个结点,作为初始节点。出队过程二者类似,注意seen数组别忘记。
class Solution:
def updateMatrix(self, mat):
seen = set()
l =len(mat)
w = len(mat[0])
queue = []
for i in range(l):
for j in range(w):
if mat[i][j] == 0:
queue.append((i,j))
seen.add((i,j))
while queue:
f,s = queue.pop(0)
for x,y in ([f-1,s],[f+1,s],[f,s-1],[f,s+1]):
if 0<=x<l and 0<=y<w and (x,y) not in seen:
mat[x][y] = mat[f][s] + 1
seen.add((x,y))
queue.append((x,y))
return mat
994. 腐烂的橘子
思路:
多源BFS。队列+seen集合。先把坏橘子(值为2)都入队。然后判断其上下左右是否没被访问,是不是=1即为橘子,满足条件就入队。注意这里需要记录层数(即题目中的耗时),在每次pop前记录queue的len即可实现。当前len长都出队了,说明这一层遍历完了,level层数+1,此外还要判断这一层是不是判空了(即最后一次可能没有橘子可以腐蚀了),这是引入一个flag变量判断,这里用了stillLive。
class Solution(object):
def orangesRotting(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
l = len(grid)
w = len(grid[0])
queue = []
seen = set()
for i in range(l):
for j in range(w):
if grid[i][j] == 2:
queue.append((i,j))
seen.add((i,j))
level = 0
while queue:
stillLive = False
size = len(queue)
for _ in range(size):
f,s = queue.pop(0)
for x,y in ([f-1,s],[f+1,s],[f,s-1],[f,s+1]):
if 0<=x<l and 0<=y<w and (x,y) not in seen and grid[x][y]==1:
grid[x][y] = 2
queue.append((x,y))
seen.add((x,y))
stillLive = True
if stillLive:
level+=1
for t in range(l):
if 1 in grid[t]:
return -1
return level