Skip to content

Clone Graph

Given a reference of a node in a connected undirected graph, return a deep copy (clone) of the graph.

Each node in the graph contains a val (int) and a neighbors list (List[Node]).

InputOutputExplanation
[[2,4],[1,3],[2,4],[1,3]]Cloned graphSame structure but different node objects
  • The number of nodes in the graph is in the range [1, 100].
  • 1 <= Node.val <= 100
  • Node.val is unique for each node.
  • There are no self-loops and no multi-edges in the graph.
ApproachTimeSpaceNotes
DFSO(n + e)O(n)Recursive traversal with hashmap
BFSO(n + e)O(n)Queue-based with hashmap

* n = number of nodes, e = number of edges

  • Pick DFS for recursive, intuitive solution.
  • Pick BFS for iterative approach and queue understanding.
Most Intuitive
DFS
O(n + e) time · O(n) space
Iterative
BFS
O(n + e) time · O(n) space
★ Recommended

Use recursive DFS to traverse the original graph while creating new nodes and mapping old to new.

⏱ Time O(n + e) Visit each node and edge once 💾 Space O(n) Hashmap for cloned nodes
clone_graph_dfs.py
from typing import Optional
from collections import defaultdict
class Node:
def __init__(self, val=0, neighbors=None):
self.val = val
self.neighbors = neighbors if neighbors is not None else []
def cloneGraphDFS(node: Optional['Node']) -> Optional['Node']:
"""
DFS approach - recursively clone nodes and build adjacency.
Time: O(n + e)
Space: O(n)
"""
if not node:
return None
visited = {}
def dfs(original: 'Node') -> 'Node':
if original.val in visited:
return visited[original.val]
cloned = Node(original.val)
visited[original.val] = cloned
for neighbor in original.neighbors:
cloned.neighbors.append(dfs(neighbor))
return cloned
return dfs(node)
✓ Simple

Use queue-based BFS to iterate through the original graph while cloning nodes.

⏱ Time O(n + e) Visit each node and edge once 💾 Space O(n) Queue + hashmap
clone_graph_bfs.py
from typing import Optional
from collections import deque
class Node:
def __init__(self, val=0, neighbors=None):
self.val = val
self.neighbors = neighbors if neighbors is not None else []
def cloneGraphBFS(node: Optional['Node']) -> Optional['Node']:
"""
BFS approach - iterate through nodes using queue.
Time: O(n + e)
Space: O(n)
"""
if not node:
return None
visited = {}
queue = deque([node])
visited[node.val] = Node(node.val)
while queue:
original = queue.popleft()
cloned = visited[original.val]
for neighbor in original.neighbors:
if neighbor.val not in visited:
visited[neighbor.val] = Node(neighbor.val)
queue.append(neighbor)
cloned.neighbors.append(visited[neighbor.val])
return visited[node.val]