Clone an undirected graph. Each node in the graph contains a
label
and a list of its neighbors
.OJ's undirected graph serialization:
Nodes are labeled uniquely.
We use #
as a separator for each node, and ,
as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph
{0,1,2#1,2#2,2}
.
The graph has a total of three nodes, and therefore contains three parts as separated by
#
.- First node is labeled as
0
. Connect node0
to both nodes1
and2
. - Second node is labeled as
1
. Connect node1
to node2
. - Third node is labeled as
2
. Connect node2
to node2
(itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1 / \ / \ 0 --- 2 / \ \_/
Solution:
Method 1: BFS
We use BFS to traverse the graph.
When we meet a node, we make a copy of it and store it into the HashMap.
We also check all its neighbors.
If any of its neighbor is not in the HashMap, we make a copy of it and store in the HashMap.
One more step: add this neighbor to the neighbor list of the current node we check.
The time complexity is O(n) and space complexity is also O(n).
Code:
/** * Definition for undirected graph. * class UndirectedGraphNode { * int label; * List<UndirectedGraphNode> neighbors; * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); } * }; */ public class Solution { public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if (node == null) { return null; } HashMap<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<>(); Queue<UndirectedGraphNode> queue = new LinkedList<>(); queue.offer(node); map.put(node, new UndirectedGraphNode(node.label)); while (!queue.isEmpty()) { UndirectedGraphNode curr = queue.poll(); for (UndirectedGraphNode nei : curr.neighbors) { if (!map.containsKey(nei)) { map.put(nei, new UndirectedGraphNode(nei.label)); queue.add(nei); } map.get(curr).neighbors.add(map.get(nei)); } } return map.get(node); } }