克隆一张无向图,图中的每个节点包含一个 label (标签)和一个 neighbors (邻接点)列表 。
OJ的无向图序列化:
节点被唯一标记。
我们用 # 作为每个节点的分隔符,用 , 作为节点标签和邻接点的分隔符。
例如,序列化无向图 {0,1,2#1,2#2,2}。
该图总共有三个节点, 被两个分隔符 # 分为三部分。
第一个节点的标签为 0,存在从节点 0 到节点 1 和节点 2 的两条边。
第二个节点的标签为 1,存在从节点 1 到节点 2 的一条边。
第三个节点的标签为 2,存在从节点 2 到节点 2 (本身) 的一条边,从而形成自环。
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {}; 这句话是在干啥,?
* };
*/
// C++ 11新特性的用法之auto
// auto关键字来要求编译器对变量name的类型进行了自动推导
//注意 C++中 空为 NULL java 中为 null
class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if(node==NULL) return NULL;
//UndirectedGraphNode *graph =new UndirectedGraphNode(node->label);//使用 new 创建结构体变量 ,//疑惑仅用node->label 就可以了初始化了?第二次看理解了:如下注释
// hash[node]=graph; //复制map 第一个进入的节点
//上述写法快 24ms 下面32ms 好理解
copy[node]=new UndirectedGraphNode(node->label); //先复制的label,neighbor在下面的for循环中复制
queue<UndirectedGraphNode*>que;
que.push(node);
while(!que.empty())
{
//auto
auto curNode =que.front();
que.pop();
for(auto val:curNode->neighbors) //for 范围循环
{
if(copy.find(val)==copy.end())//end返回一个迭代器,指向指定的桶的末尾 ,find(val),指向键等于 key 的元素的迭代器。若找不到这种元素,则返回尾后(见 end() )迭代器
{
copy[val]= new UndirectedGraphNode(val->label);//存储相当于做了标记
que.push(val);
}
copy[curNode]->neighbors.push_back(copy[val]);//neither 复制
}
}
return copy[node];
}
private:
//建立节点 clone hash map
unordered_map<UndirectedGraphNode*,UndirectedGraphNode*>copy;
};