Table of Contents
What is Graph Cloning?
Today we have with us a reference to an undirected graph. What do we have to do? Returning a deep copy of the provided graph.
Let us look at the structure:
The Class Node:
It consists of the data value and the neighbors associated with each object of this class. There are a few methods as well to create objects/new nodes accordingly.
class Node {
public int val;
public List<Node> neighbors;
public Node() {
val = 0;
neighbors = new ArrayList<Node>();
}
public Node(int _val) {
val = _val;
neighbors = new ArrayList<Node>();
}
public Node(int _val, ArrayList<Node> _neighbors) {
val = _val;
neighbors = _neighbors;
}
}
The node given to us will always be the root node. Returning a reference/copy to the root will help us return the clone of the graph we have been provided with.
Sample test case:

Input : [[1,2],[2,3],[3,4],[4,5],[1,2]]
Output : [[1,2],[2,3],[3,4],[4,5],[1,2]]
The clone should look something like

i.e consisting of the copy of the nodes which have the same values.
Disclaimer: Do not return the same graph
Solution
Using Breadth-First Search and HashMap
We can traverse through using BFS and maintain a HashMap for keeping a mapping of the original and the clone nodes.
Pseudocode
- Create a hashmap
- Add the root node and the copy to the hashmap
- Put the root node to the stack
- Traverse through the neighbours and keep repeating the above process
- Add the neighbours for each node
- Keep repeating the above process until the queue gets empty
For more reference lookup BFS: Breadth-First Search (BFS) for a Graph(Opens in a new browser tab)
Here is a simple image to illustrate the above process

Now that we have got a basic idea of how to do stuff let us get into the code
Java Program for Graph Cloning
class Solution
{
public Node cloneGraph(Node node)
{
if(node==null)
return null;
//Creating a Queue for BFS
Queue<Node>store=new LinkedList<Node>();
//Adding the root node
store.add(node);
//Creating a hashmap of nodes and copies
HashMap<Node,Node>hash=new HashMap<Node,Node>();
hash.put(node,new Node(node.val));
//Firing up the BFS!
while(!store.isEmpty())
{
Node cur=store.poll();
for(Node neigh:cur.neighbors)
{
if(!hash.containsKey(neigh))
{
hash.put(neigh,new Node(neigh.val));
store.add(neigh);
}
//Adding the neighbours to the duplicate nodes
hash.get(cur).neighbors.add(hash.get(neigh));
}
}
return(hash.get(node));
}
}C++ Program for Graph Cloning
class Solution
{
public:
Node* cloneGraph(Node* node)
{
if(!node)
return NULL;
//Creating a Queue for BFS
queue<Node*>store;
//Adding the root node
store.push(node);
//Creating a hashmap of nodes and copies
map<Node*,Node*>hash;
hash[node]=new Node(node->val,{});
//Firing up the BFS!
while(!store.empty())
{
Node* cur=store.front();
store.pop();
for(Node* neigh:cur->neighbors)
{
if(hash.count(neigh)==0)
{
hash[neigh]=new Node(neigh->val,{});
store.push(neigh);
}
//Adding the neighbours to the duplicate nodes
hash[cur]->neighbors.push_back(hash[neigh]);
}
}
return(hash[node]);
}
};[[1,2],[2,3],[3,4],[4,5],[1,2]]
[[1,2],[2,3],[3,4],[4,5],[1,2]]
Complexity Analysis
Time complexity=O(V+E)
Space complexity=O(n)
V=Number of Vertices
E=Number of Edges
How did the time and space complexity end up to this?
- We have in the code a loop emptying the queue that runs over V times. In the loop
- We remove data from the queue=O(1) operation
- Traverse all the neighbour edges to get the clones=O(Adj)
- Add neighbours=O(1) operation
- Summing up the complexity=V*(O(1)+O(Adj)+O(1))
- Which boils down to O(V)+O(V*Adj)
- Making the time complexity=O(V+E)
- The space complexity is O(n) as all we needed was a queue