代码仓库:Github | Leetcode solutions @doubleZ0108 from Peking University.
这题真的很好!
- 解法1(T75% S14%):本质上是求一个连通图到另一个连通图的最短距离,是一道DFS+BFS的题。为什么需要DFS呢?因为这里面有两个图,需要一次DFS完全找到一个图,将二者区分。为什么需要BFS呢?按宽度遍历可以找到最近的桥。因此首先遍历二维数组找到第一个1,也就是找到第一个图的一个点,然后一遍DFS把整个图1都标上数字2以区分,并将所有图1的节点加入一个队列。然后依次出队进行BFS扩展,直到某次扩展找到了另一张图中某个点,最短桥也就找到了。
class Solution(object):
def shortestBridge(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
N = len(grid)
def DFS(x, y):
if x<0 or y<0 or x>N-1 or y>N-1: return
if grid[x][y] != 1: return
if grid[x][y] == 1:
grid[x][y] = 2
S.add((x, y))
DFS(x+1, y)
DFS(x-1, y)
DFS(x, y+1)
DFS(x, y-1)
def BFS():
queue = []
visited = set()
for s in S:
queue.append((s,0))
visited.add(s)
while queue:
(i, j), step = queue.pop(0)
if grid[i][j] == 1: return step-1
for x, y in [(i-1,j),(i,j-1),(i+1,j),(i,j+1)]:
if x>=0 and y>=0 and x<=N-1 and y<=N-1:
if (x,y) not in visited:
visited.add((x,y))
queue.append(((x,y),step+1))
S = set()
flag = False
for i in range(N):
for j in range(N):
if grid[i][j] == 1:
DFS(i, j)
flag = True
break
if flag: break
return BFS()