Question
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 node 0
to both nodes 1
and 2
.
Second node is labeled as 1
. Connect node 1
to node 2
.
Third node is labeled as 2
. Connect node 2
to node 2
(itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1 / \ / \ 0 --- 2 / \ \_/
本题难度Medium。有2种算法分别是: BFS和DFS。(两者是一样的,我只写BFS)
BFS
【复杂度】
时间 O(N) 空间 O(N)
【难点】
实际上难点就在于{4,4}
、{3,4,4}
这种,可能会出现4
的重复创建错误(前后创建了两个4
)。
【思路】
将BFS遍历到的在新图中尚未建立关联的节点放入队列q
中,用一个哈希表map
,将新旧节点映射起来。这样我们第一次遍历到的节点,我们会新建一个节点并映射到哈希表中;当以后再遍历到这个节点时,我们可以直接用哈希表取出它对应的新节点。我们只要保证,对于第一次遇到的节点,我们都会建立一个克隆节点,并在哈希表映射起来就行了。
【要点】
队列:存放新图中尚未建立关联的节点
哈希表:存放凡是放入过队列的节点
【代码】
/**
* 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) {
//require
if(node==null)return null;
Queue<UndirectedGraphNode> q=new LinkedList<>();
Map<UndirectedGraphNode,UndirectedGraphNode> map=new HashMap<>();
UndirectedGraphNode head=new UndirectedGraphNode(node.label);
q.offer(node);
map.put(node,head);
//invariant
while(!q.isEmpty()){
UndirectedGraphNode cur=q.poll();
for(UndirectedGraphNode n:cur.neighbors){
if(!map.containsKey(n)){
q.offer(n);
map.put(n,new UndirectedGraphNode(n.label));
}
map.get(cur).neighbors.add(map.get(n));
}
}
//ensure
return head;
}
}