Leetcode 133:克隆圖(超詳細的解法!!!)
阿新 • • 發佈:2019-01-09
克隆一張無向圖,圖中的每個節點包含一個 label
(標籤)和一個 neighbors
(鄰接點)列表 。
OJ的無向圖序列化:
節點被唯一標記。
我們用 #
作為每個節點的分隔符,用 ,
作為節點標籤和鄰接點的分隔符。
例如,序列化無向圖 {0,1,2#1,2#2,2}
。
該圖總共有三個節點, 被兩個分隔符 #
分為三部分。
- 第一個節點的標籤為
0
,存在從節點0
到節點1
和節點2
的兩條邊。 - 第二個節點的標籤為
1
,存在從節點1
到節點2
的一條邊。 - 第三個節點的標籤為
2
,存在從節點2
到節點2
(本身) 的一條邊,從而形成自環。
我們將圖形視覺化如下:
1
/ \
/ \
0 --- 2
/ \
\_/
解題思路
考察DFS
和BFS
操作,首先使用BFS
。
class Solution:
# @param node, a undirected graph node
# @return a undirected graph node
def cloneGraph(self, node):
if not node:
return None
queue = [node]
copy_node = UndirectedGraphNode(node.label)
visited = {node: copy_node}
while queue:
node = queue.pop(0)
for i in node.neighbors:
if i in visited:
visited[node].neighbors.append(visited[i])
else :
copy_node_ne = UndirectedGraphNode(i.label)
visited[node].neighbors.append(copy_node_ne)
visited[i] = copy_node_ne
queue.append(i)
return copy_node
DFS
操作只要將queue
換成stack
即可。
class Solution:
# @param node, a undirected graph node
# @return a undirected graph node
def cloneGraph(self, node):
if not node:
return None
stack = [node]
copy_node = UndirectedGraphNode(node.label)
visited = {node: copy_node}
while stack:
node = stack.pop()
for i in node.neighbors:
if i in visited:
visited[node].neighbors.append(visited[i])
else:
copy_node_ne = UndirectedGraphNode(i.label)
visited[node].neighbors.append(copy_node_ne)
visited[i] = copy_node_ne
stack.append(i)
return copy_node
同樣可以快速的寫出遞迴版本的DFS
。
class Solution:
# @param node, a undirected graph node
# @return a undirected graph node
def cloneGraph(self, node):
if not node:
return None
copy_node = UndirectedGraphNode(node.label)
visited = {node: copy_node}
self.dfs(node, visited)
return copy_node
def dfs(self, node, visited):
for i in node.neighbors:
if i in visited:
visited[node].neighbors.append(visited[i])
else:
copy_node_ne = UndirectedGraphNode(i.label)
visited[node].neighbors.append(copy_node_ne)
visited[i] = copy_node_ne
self.dfs(i, visited)
一個更好的解法。
class Solution:
def __init__(self):
self.visited = dict()
def cloneGraph(self, node):
if not node:
return None
if node not in self.visited:
self.visited[node] = UndirectedGraphNode(node.label)
for i in node.neighbors:
self.visited[node].neighbors.append(self.cloneGraph(i))
return self.visited[node]
我將該問題的其他語言版本新增到了我的GitHub Leetcode
如有問題,希望大家指出!!!