原題
克隆一張無向圖,圖中的每個節點包含一個 label 和一個表 neighbors。
你的程序需要返回一個經過深度拷貝的新圖。這個新圖和原圖具有同樣的結構,并且對新圖的任何改動不會對原圖造成任何影響。
樣例
比如,序列化圖 {0,1,2#1,2#2,2} 共有三個節點, 因此包含兩個個分隔符#。
第一個節點label為0,存在邊從節點0鏈接到節點1和節點2
第二個節點label為1,存在邊從節點1連接到節點2
第三個節點label為2,存在邊從節點2連接到節點2(本身),從而形成自環。
我們能看到如下的圖:
1
/ \
/ \
0 --- 2
/ \
\_/
解題思路
- 首先,要遍歷無向圖,需要使用Hash Map來當作visited數組,防止重復訪問而造成程序中的死循環
- 遍歷圖有兩種方式 - BFS & DFS,本題均可采用
- BFS - 使用Queue (prefer)
- DFS - 遞歸或者使用Stack,對于DFS,每次clone一個node的時候,就要把它所有的neighbor加入到新clone的node的neighbor中,此時recursivly調用dfs,如果沒有visited過 - 新建一個node,否則直接從map中找到返回
- 在visited數組中,key值為原來的node,value為新clone的node,如果一個node不存在于map中,說明這個node還未被clone,將它clone后放入queue中繼續處理neighbors
完整代碼
# Method 1: BFS
# Definition for a undirected graph node
# class UndirectedGraphNode(object):
# def __init__(self, x):
# self.label = x
# self.neighbors = []
import Queue
class Solution(object):
def __init__(self):
self.visited = {}
def cloneGraph(self, node):
"""
:type node: UndirectedGraphNode
:rtype: UndirectedGraphNode
"""
if not node:
return None
newHead = UndirectedGraphNode(node.label)
self.visited[node] = newHead
myQueue = Queue.Queue()
myQueue.put(node)
while myQueue.qsize():
current = myQueue.get()
for neighbor in current.neighbors:
if neighbor not in self.visited:
newNode = UndirectedGraphNode(neighbor.label)
self.visited[current].neighbors.append(newNode)
self.visited[neighbor] = newNode
myQueue.put(neighbor)
else: # turn directed graph to undirected graph
self.visited[current].neighbors.append(self.visited[neighbor])
return newHead
# Method 2: DFS
class Solution(object):
def cloneGraph(self, node):
"""
:type node: UndirectedGraphNode
:rtype: UndirectedGraphNode
"""
if not node:
return None
return self.dfs(node, {})
def dfs(self, node, map):
if node in map:
return map[node]
newNode = UndirectedGraphNode(node.label)
map[node] = newNode
for neighbor in node.neighbors:
newNode.neighbors.append(self.dfs(neighbor, map))
return newNode