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.
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 private Map<Node, Node> visited = new HashMap<>();
22
23 public Node cloneGraph(Node node) {
24 if (node == null) return null;
25
26 if (visited.containsKey(node)) {
27 return visited.get(node);
28 }
29
30 Node cloneNode = new Node(node.val, new ArrayList<>());
31 visited.put(node, cloneNode);
32
33 for (Node neighbor : node.neighbors) {
34 cloneNode.neighbors.add(cloneGraph(neighbor));
35 }
36 return cloneNode;
37 }
38}
The Java solution involves using a HashMap
to track visited nodes. cloneGraph
recursively clones each node and its neighbors if not already cloned, ensuring that each node is processed once.
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).
1function Node(val, neighbors) {
2 this.val = val;
3 this.neighbors = neighbors ? neighbors : [];
4};
5
6var cloneGraph = function(node) {
7 if (!node) return null;
8 const visited = new Map();
9 const queue = [node];
10 visited.set(node, new Node(node.val));
11
12 while (queue.length) {
13 const n = queue.shift();
14 for (const neighbor of n.neighbors) {
15 if (!visited.has(neighbor)) {
16 visited.set(neighbor, new Node(neighbor.val));
17 queue.push(neighbor);
18 }
19 visited.get(n).neighbors.push(visited.get(neighbor));
20 }
21 }
22 return visited.get(node);
23};
The JavaScript solution for graph cloning uses a queue for BFS traversal, maintaining a map to record cloned nodes. Level-wise cloning and linking are handled within the while loop. This guarantees efficient processing and avoids deep recursion.