题目描述
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:
本题要求对无向图进行复制。因此本题主要涉及到指针操作,以及深拷贝的概念。从上面的例子图片可以看出,图可能存在自循环,即2号节点同时会指向自己,并且图之间的指向是双向的。因此,我们在实现的时候需要注意哪些节点已经生成了,避免重复操作陷入死循环。题目已经说明,节点的label是唯一的,我们的程序中需要利用本特性。
例如,在生成0号节点的neighbor可以得到1号和2号节点,此时需要生成1号和2号节点。在生成1号节点的时,又会得到其neighbor:0号节点,此时若再生成0,则会陷入死循环。因此,针对label唯一的特性,我们可以使用一个map记录已经生成的node。如果node为生成,则生成新node,若已生成,则将其指针添加到neighbor中即可。
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
UndirectedGraphNode *clone(UndirectedGraphNode *node, map<int, UndirectedGraphNode*> &labels) {
if (node == NULL)
{
return NULL;
}
if(labels.find(node->label) != labels.end()) //node exist
return labels.find(node->label)->second;
UndirectedGraphNode *g = new UndirectedGraphNode(node->label);
labels[node->label] = g;
for(int i = 0; i < node->neighbors.size(); ++i)
{
g->neighbors.push_back(clone(node->neighbors[i], labels));
}
return g;
}
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
map<int, UndirectedGraphNode*> labels;
return clone(node, labels);
}
};