The Depth-First Search (DFS) approach is one of the most intuitive ways to solve the graph cloning problem. Here, we will recursively explore each node starting from the root (Node 1) and keep a map to store already cloned nodes, ensuring each node is cloned once.
For each node, we:
Time Complexity: O(V+E), where V is the number of vertices and E is the number of edges. This is because we visit each node and edge once.
Space Complexity: O(V), for the recursion stack and the clone map.
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#define MAX_NODES 101
6
7typedef struct Node {
8 int val;
9 struct Node** neighbors;
10 int numNeighbors;
11} Node;
12
13Node* cloneGraph(Node* node, Node** cloneMap);
14
15Node* cloneGraphUtil(Node* node, Node** cloneMap) {
16 if (node == NULL) return NULL;
17
18 if (cloneMap[node->val]) return cloneMap[node->val];
19
20 Node* cloneNode = (Node*)malloc(sizeof(Node));
21 cloneNode->val = node->val;
22 cloneNode->numNeighbors = node->numNeighbors;
23 cloneNode->neighbors = (Node**)malloc(sizeof(Node*) * node->numNeighbors);
24 cloneMap[node->val] = cloneNode;
25
26 for (int i = 0; i < node->numNeighbors; i++) {
27 cloneNode->neighbors[i] = cloneGraphUtil(node->neighbors[i], cloneMap);
28 }
29
30 return cloneNode;
31}
32
33Node* cloneGraph(Node* node) {
34 Node* cloneMap[MAX_NODES] = {NULL};
35 return cloneGraphUtil(node, cloneMap);
36}
The above C program defines a structure Node
for graph nodes and uses a recursive function cloneGraphUtil
to perform a DFS for cloning. We use an array of pointers cloneMap
indexed by node values to track cloned nodes.
An alternative approach is to use Breadth-First Search (BFS), which is iterative in nature. Here, we utilize a queue to help explore each node level by level, preventing deep recursion and managing each node's clone in a breadth-wise manner.
In this BFS approach:
Time Complexity: O(V+E).
Space Complexity: O(V).
1import java.util.*;
2
3class Node {
4 public int val;
5 public List<Node> neighbors;
6 public Node() {
7 val = 0;
8 neighbors = new ArrayList<Node>();
9 }
10 public Node(int _val) {
11 val = _val;
12 neighbors = new ArrayList<Node>();
13 }
14 public Node(int _val, ArrayList<Node> _neighbors) {
15 val = _val;
16 neighbors = _neighbors;
17 }
18}
19
20class Solution {
21 public Node cloneGraph(Node node) {
22 if (node == null) return null;
23
24 Map<Node, Node> visited = new HashMap<>();
25 Queue<Node> queue = new LinkedList<>();
26 queue.add(node);
27 visited.put(node, new Node(node.val, new ArrayList<>()));
28
29 while (!queue.isEmpty()) {
30 Node n = queue.poll();
31 for (Node neighbor : n.neighbors) {
32 if (!visited.containsKey(neighbor)) {
33 visited.put(neighbor, new Node(neighbor.val, new ArrayList<>()));
34 queue.add(neighbor);
35 }
36 visited.get(n).neighbors.add(visited.get(neighbor));
37 }
38 }
39 return visited.get(node);
40 }
41}
This Java BFS solution involves using a queue to iteratively process and clone nodes level by level. The map visited
ensures each node is cloned exactly once, and relationships are established as nodes are dequeued and processed.