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 1:
BFS
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
if(node == null) return null;
Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<>();
UndirectedGraphNode cloned = new UndirectedGraphNode(node.label);
map.put(node,cloned);
Queue<UndirectedGraphNode> queue = new LinkedList<>();
queue.offer(node);
while(!queue.isEmpty()) {
UndirectedGraphNode u = queue.poll();
UndirectedGraphNode v = map.get(u);
for(UndirectedGraphNode n: u.neighbors) {
UndirectedGraphNode copied = map.get(n);
if(copied == null) {
copied = new UndirectedGraphNode(n.label);
map.put(n, copied);
queue.offer(n);
}
v.neighbors.add(copied);
}
}
return cloned;
}
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if(!node) return nullptr;
queue<UndirectedGraphNode*> q;
unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> gmap;
gmap[node] = new UndirectedGraphNode(node->label);
q.push(node);
while(!q.empty()) {
UndirectedGraphNode *n = q.front();
q.pop();
for(auto neighbor:n->neighbors) {
if(gmap.count(neighbor) == 0) {
gmap[neighbor] = new UndirectedGraphNode(neighbor->label);
q.push(neighbor);
}
gmap[n]->neighbors.push_back(gmap[neighbor]);
}
}
return gmap[node];
}
Solution 2:
DFS
private Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<>();
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
if(node == null) return null;
UndirectedGraphNode clonedNode = new UndirectedGraphNode(node.label);
List<UndirectedGraphNode> neighbors = clonedNode.neighbors;
for(UndirectedGraphNode n:node.neighbors) {
if(n.label == node.label) {
neighbors.add(clonedNode);
continue;
}
if(map.containsKey(n)) {
neighbors.add(map.get(n));
} else {
UndirectedGraphNode value = cloneGraph(n);
neighbors.add(value);
map.put(n, value);
}
}
return clonedNode;
}
unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> gmap;
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if(!node) return nullptr;
if(gmap.count(node) == 0) {
gmap[node] = new UndirectedGraphNode(node->label);
for(auto neighbor:node->neighbors) {
gmap[node]->neighbors.push_back(cloneGraph(neighbor));
}
}
return gmap[node];
}