Given a reference of a node in a connected undirected graph.
Return a deep copy (clone) of the graph.
solutions
bfs
We can BFS, making sure to traverse each node only once. Whenever we pop a node, we add all of its neighbors to node.neighbors, creating new cloned nodes and adding them to our mapping dictionary if necessary. If the node has not yet been processed, enqueue it.
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
if not node:
return None
d = {node: Node(node.val)}
q = deque([node])
while q:
cur = q.popleft()
for neighbor in cur.neighbors:
# only visit each node once
if neighbor not in d:
new_neighbor = Node(neighbor.val)
d[neighbor] = new_neighbor
q.append(neighbor)
# store all neighbor relationships
d[cur].neighbors.append(d[neighbor])
return d[node]dfs
We can also similarly DFS while maintaining a map between old and new nodes. Make sure to add to the hashmap right when we clone it and not after we recurse.
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
clones = {}
def dfs(node):
if not node:
return node
clone = Node(node.val)
clones[node.val] = clone
for neighbor in node.neighbors:
if neighbor.val in clones:
clone.neighbors.append(clones[neighbor.val])
else:
clone.neighbors.append(dfs(neighbor))
return clone
return dfs(node)