Leetcode 133 - Clone Graph
Understanding the Problem
The goal is to create a deep copy of a connected undirected graph. Each node in the graph contains:
- A unique integer value (
val) - A list of neighboring nodes (
neighbors)
A deep copy means every node in the original graph must have a newly created counterpart with the same value and neighbor relationships, but without sharing any references with the original graph.
A natural approach is to perform a Breadth-First Search (BFS) starting from the given node while maintaining a mapping from original nodes to their cloned nodes.
- State Tracking: A dictionary
old_to_newmaps each original node to its cloned node. This ensures each node is cloned exactly once and prevents infinite traversal caused by cycles. - Initialization: Clone the starting node and place the original node into the BFS queue.
- Traversal: For every node dequeued:
- Visit each of its neighbors.
- If a neighbor has not yet been cloned, create its clone, store it in the dictionary, and enqueue the original neighbor.
- Append the cloned neighbor to the cloned current node's
neighborslist. - Cycle Handling: Since graphs may contain cycles, checking whether a node already exists in
old_to_newprevents revisiting and recloning the same node.
Solution Implementation
Code
from collections import deque
from typing import Optional
class Solution:
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
if not node:
return None
old_to_new = {node: Node(node.val)}
q = deque([node])
while q:
curr = q.popleft()
for nei in curr.neighbors:
if nei not in old_to_new:
old_to_new[nei] = Node(nei.val)
q.append(nei)
old_to_new[curr].neighbors.append(old_to_new[nei])
return old_to_new[node]
Time Complexity
Each node is visited exactly once during the BFS traversal, and every edge is processed exactly once when building the neighbor lists of the cloned graph.
For a graph with V vertices and E edges:
Overall time complexity — \(O(V + E)\)
Space Complexity
- Hash Map: Stores one cloned node for every original node, requiring \(O(V)\) space.
- Queue: In the worst case, the BFS queue may contain up to \(O(V)\) nodes.
- The cloned graph itself also contains \(O(V + E)\) nodes and edges, but this is required output space and is typically not counted as auxiliary space.
Overall auxiliary space complexity — \(O(V)\)
Key Takeaways
- Use a hash map to maintain a one-to-one mapping between original nodes and cloned nodes.
- Clone each node only once. Reuse the existing clone whenever the node is encountered again.
- The hash map simultaneously serves as a visited set, preventing infinite loops in cyclic graphs.
- As each original edge is traversed, connect the corresponding cloned nodes to reconstruct the graph structure.
Additional Resources
- https://neetcode.io/problems/clone-graph
- https://leetcode.com/problems/clone-graph/