Problem
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 value (int) and a list (List[Node]) of its neighbors.
| |
OR
| |
Test case format:
For simplicity, each node’s value is the same as the node’s index (1-indexed). For example, the first node with val == 1, the second node with val == 2, and so on. The graph is represented in the test case using an adjacency list.
An adjacency list is a collection of unordered lists used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.
The given node will always be the first node with val = 1. You must return the copy of the given node as a reference to the cloned graph.
Examples
Example 1:
graph LR
subgraph Original
A1[1]:::orig
B1[2]:::orig
C1[3]:::orig
D1[4]:::orig
A1 --- B1 & D1
B1 --- C1
D1 --- C1
end
subgraph Same["Don't return same graph"]
A2[1]:::orig
B2[2]:::orig
C2[3]:::orig
D2[4]:::orig
A2 --- B2 & D2
B2 --- C2
D2 --- C2
end
subgraph Correct["Looks same + new nodes"]
A3[1]:::corr
B3[2]:::corr
C3[3]:::corr
D3[4]:::corr
A3 --- B3 & D3
B3 --- C3
D3 --- C3
end
subgraph Messy["Wrong connections"]
A4[1]:::mess
B4[3]:::mess
C4[2]:::mess
D4[4]:::mess
A4 --- B4 & D4
B4 --- C4
D4 --- C4
end
Original --x Same
Original --> Correct
Original --x Messy
classDef orig stroke:#FF8C00,stroke-width:2px
classDef corr stroke:blue,stroke-width:2px
classDef mess stroke:#f66,stroke-width:2px
| |
Example 2:
graph LR; A(1)
| |
Example 3:
| |
Solution
A graph clone requires creating a copy of each node and appropriately linking its neighbours in the clone while ensuring each node is cloned only once. So, we can use DFS or BFS to traverse through the graph starting from the given node.
Method 1 - DFS
Approach
- Mapping
- Maintain a hashmap (or dictionary)
visitedthat maps each original node to its clone. - If a node has already been cloned, use the clone from the hashmap.
- If not, create a new clone and add it to the hashmap.
- Maintain a hashmap (or dictionary)
- Build the clone
- For each node, recursively (or iteratively) visit its neighbours and add the clones’ neighbours accordingly.
We can use origToCopyMap containing node and cloned node.
Code
| |
| |
Complexity
- ⏰ Time complexity:
O(V + E)whereVis the number of vertices (nodes) andEis the number of edges, since we visit each node and edge once. - 🧺 Space complexity:
O(V)for the hashmap and the recursion/queue stack, whereVis the number of nodes.
Method 2 - BFS
We can use BFS by:
- Using a queue, we systematically visit each node layer by layer.
- We create a clone for each node and link its neighbours as we traverse.
Algorithm
- If the input node is
null, returnnull. - Initialise a mapping (
visited) that stores the reference to already cloned nodes. - Use a queue to traverse the graph.
- For each node:
- Clone the node if it hasn’t been cloned already (using
visitedas a check). - Traverse its neighbours, clone them (if necessary), and connect the current node’s clone to its neighbours’ clones.
- Add unvisited neighbours to the queue.
- Clone the node if it hasn’t been cloned already (using
- Once all nodes are processed, the graph is fully cloned.
| |
Complexity
- ⏰ Time complexity:
O(V+E), because BFS ensures each node and edge is visited once. - 🧺 Space complexity:
O(V)for the hashmap and the BFS queue.