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 node0to both nodes1and2. - Second node is labeled as
1. Connect node1to node2. - Third node is labeled as
2. Connect node2to node2(itself), thus forming a self-cycle.
1
/ \
/ \
0 --- 2
/ \
\_/
The key idea is to use a HashMap to record the mapping relationship of the original node and copied node. We start from on unvisited node, make a copy of it, and insert this mapping relation into the hashmap. Then we start to copy the neighbors, if we find a node that is not contained in the hashmap, then this indicates that we have another unvisited node, we recurse on this node. After the recursion, the node has had a copy, then we could add this copy to the neighbors. Be careful when the input is null since hashmap does not allow null to be inserted and this would be a corner case.
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
if(node == null)
return null; // corner case
HashMap<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
dfs(node, map);
return map.get(node);
}
private void dfs(UndirectedGraphNode node, HashMap<UndirectedGraphNode, UndirectedGraphNode> map) {
UndirectedGraphNode newNode = new UndirectedGraphNode(node.label);
map.put(node, newNode); // mark as visited
for(UndirectedGraphNode un : node.neighbors) { // copy neighbors
if(map.containsKey(un) == false) // if neighbor not visited, there is no copyed node, recurse on this node
dfs(un, map);
newNode.neighbors.add(map.get(un));
}
}
没有评论:
发表评论