难度: Medium
原题连接
内容描述
Given the head of a graph, return a deep copy (clone) of the graph. Each node in the graph contains a label (int) and a list (List[UndirectedGraphNode]) of its neighbors. There is an edge between the given node and each of the nodes in its neighbors.
OJ's undirected graph serialization (so you can understand error output):
Nodes are labeled uniquely.
We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}.
The graph has a total of three nodes, and therefore contains three parts as separated by #.
First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
Second node is labeled as 1. Connect node 1 to node 2.
Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1
/ \
/ \
0 --- 2
/ \
\_/
Note: The information about the tree serialization is only meant so that you can understand error output if you get a wrong answer. You don't need to understand the serialization to solve the problem.
思路 1 - 时间复杂度: O(V + E)- 空间复杂度: O(V)******
DFS iterative
class Solution:
# @param node, a undirected graph node
# @return a undirected graph node
def cloneGraph(self, node):
if not node:
return
stack = [node]
res = UndirectedGraphNode(node.label)
visited = {node.label: res}
while stack:
cur = stack.pop()
if cur.label not in visited: # 这个node没有被构造,那么就构造它然后放进字典里
new_cur = UndirectedGraphNode(cur.label)
lookup[cur.label] = new_cur
for neighbor in cur.neighbors:
if neighbor.label not in visited: # 如果是还未构造的node才放进栈里面
new_neighbor = UndirectedGraphNode(neighbor.label)
visited[neighbor.label] = new_neighbor
stack.append(neighbor)
visited[cur.label].neighbors.append(visited[neighbor.label])
return res
思路 2 - 时间复杂度: O(V + E)- 空间复杂度: O(V)******
BFS iterative,其实就是改变一下pop的顺序而已
class Solution:
# @param node, a undirected graph node
# @return a undirected graph node
def cloneGraph(self, node):
if not node:
return
stack = [node]
res = UndirectedGraphNode(node.label)
visited = {node.label: res}
while stack:
cur = stack.pop(0)
if cur.label not in visited: # 这个node没有被构造,那么就构造它然后放进字典里
new_cur = UndirectedGraphNode(cur.label)
lookup[cur.label] = new_cur
for neighbor in cur.neighbors:
if neighbor.label not in visited: # 如果是还未构造的node才放进栈里面
new_neighbor = UndirectedGraphNode(neighbor.label)
visited[neighbor.label] = new_neighbor
stack.append(neighbor)
visited[cur.label].neighbors.append(visited[neighbor.label])
return res
思路 3 - 时间复杂度: O(V + E)- 空间复杂度: O(V)******
DFS recursive
class Solution:
# @param node, a undirected graph node
# @return a undirected graph node
def cloneGraph(self, node):
if not node:
return
def dfs(node):
if node.label in visited:
return visited[node.label]
new_node = UndirectedGraphNode(node.label)
visited[new_node.label] = new_node
new_node.neighbors = [dfs(n) for n in node.neighbors]
return new_node
visited = {}
return dfs(node)