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 / \ \_/
可以分两次遍历,第一次遍历生成所有的新结点以及新节点和老结点的对应关系,存储在unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> map里面,
第二次遍历 利用map中对对应关系 将 新图的邻居neighbors赋值,参考:http://blog.youkuaiyun.com/lanxu_yy/article/details/17802415
但是可以利用map查看是否已经有了该节点的副本,所以可以不用两次遍历
BFS:当要设置某个结点map[tmpN]的邻居的时候,可以先在map中查看是否存在该邻居的副本nb,有了就这是设置map[tmpN]的邻居为nb的副本,否则就new以nb的副本,再设置,同时要把nb加入需要设置邻居的队列。
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if(node==NULL)
return NULL;
unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> old_new;
queue<UndirectedGraphNode *> currQ;//存储老的结点,这些老结点已经生成对应新结点了,但是他们的邻居还没处理
currQ.push(node);
old_new[node]=new UndirectedGraphNode(node->label);
while(currQ.size()>0)
{
UndirectedGraphNode *tmpN=currQ.front();
currQ.pop();
for(auto nb : tmpN->neighbors) //处理tmpN的邻居结点---- old_new[tmpN]->neighbors
{
if(old_new.count(nb)==0) // 它的邻居还没生
{
old_new[nb]=new UndirectedGraphNode(nb->label);
old_new[tmpN]->neighbors.push_back(old_new[nb]);//添加邻居
// nb刚刚拷贝了,但是它的邻居还没处理,所以要加入队列,注意不是新生的结点old_new[nb]加入队列,而是nb加入队列!!
currQ.push(nb);
}
else
old_new[tmpN]->neighbors.push_back(old_new[nb]); //要添加old_new[nb],不是nb,不是nb,不是nb
}
}
return old_new[node];
}
};
DFS:
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
UndirectedGraphNode *dfsClone( UndirectedGraphNode *node,
unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> &old_new)
{
if(old_new.count(node)==0)
{
old_new[node]=new UndirectedGraphNode(node->label);
for(auto nb : node->neighbors )
old_new[node]->neighbors.push_back(dfsClone(nb,old_new));
}
return old_new[node];
}
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node)
{
if(node==NULL)
return NULL;
unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> old_new;
dfsClone(node,old_new);
return old_new[node];
}
};