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 <vector>
2#include <unordered_map>
3using namespace std;
4
5class Node {
6public:
7 int val;
8 vector<Node*> neighbors;
9 Node() {
10 val = 0;
11 neighbors = vector<Node*>();
12 }
13 Node(int _val) {
14 val = _val;
15 neighbors = vector<Node*>();
16 }
17 Node(int _val, vector<Node*> _neighbors) {
18 val = _val;
19 neighbors = _neighbors;
20 }
21};
22
23class Solution {
24public:
25 unordered_map<Node*, Node*> visited;
26
27 Node* cloneGraph(Node* node) {
28 if (!node) return NULL;
29 if (visited.find(node) != visited.end())
30 return visited[node];
31
32 Node* cloneNode = new Node(node->val);
33 visited[node] = cloneNode;
34
35 for (auto neighbor : node->neighbors) {
36 cloneNode->neighbors.push_back(cloneGraph(neighbor));
37 }
38 return cloneNode;
39 }
40};
This C++ solution utilizes a class Node
and a class Solution
. The cloneGraph
function checks if a node is already cloned via the visited
map, ensures deep copying by recursively cloning neighbors, and returns the deep clone of the input node.
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).
1using System;
2using System.Collections.Generic;
3
4public class Node {
5 public int val;
6 public IList<Node> neighbors;
7 public Node() {
8 val = 0;
9 neighbors = new List<Node>();
10 }
11 public Node(int _val) {
12 val = _val;
13 neighbors = new List<Node>();
14 }
15 public Node(int _val, List<Node> _neighbors) {
16 val = _val;
17 neighbors = _neighbors;
18 }
19}
20
21public class Solution {
22 public Node CloneGraph(Node node) {
23 if (node == null) return null;
24
25 Dictionary<Node, Node> visited = new Dictionary<Node, Node>();
26 Queue<Node> queue = new Queue<Node>();
27 queue.Enqueue(node);
28 visited[node] = new Node(node.val, new List<Node>());
29
30 while (queue.Count > 0) {
31 var n = queue.Dequeue();
32 foreach (var neighbor in n.neighbors) {
33 if (!visited.ContainsKey(neighbor)) {
34 visited[neighbor] = new Node(neighbor.val, new List<Node>());
35 queue.Enqueue(neighbor);
36 }
37 visited[n].neighbors.Add(visited[neighbor]);
38 }
39 }
40 return visited[node];
41 }
42}
The C# solution employs a BFS approach with a queue, similar to other languages. A dictionary visited
is used to track cloned nodes. The iterative nature ensures efficient node processing with level order traversal.