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.
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)); } }
没有评论:
发表评论