克隆一张无向图,图中的每个节点包含一个 label
和一个列表 neighbors
。
数据中如何表示一个无向图?http://www.lintcode.com/help/graph/
你的程序需要返回一个经过深度拷贝的新图。这个新图和原图具有同样的结构,并且对新图的任何改动不会对原图造成任何影响。
样例
比如,序列化图 {0,1,2#1,2#2,2}
共有三个节点, 因此包含两个个分隔符#。
- 第一个节点label为0,存在边从节点0链接到节点1和节点2
- 第二个节点label为1,存在边从节点1连接到节点2
- 第三个节点label为2,存在边从节点2连接到节点2(本身),从而形成自环。
我们能看到如下的图:
1 / \ / \ 0 --- 2 / \ \_/
思路:无向图深拷贝,按照深度优先的方法就能完成。最重要是在拷贝的时候做到对于旧点与新点的一一对应,以及深度优先搜索里面重复访问点的去除。
代码:
/** * Definition for undirected graph. * struct UndirectedGraphNode { * int label; * vector<UndirectedGraphNode *> neighbors; * UndirectedGraphNode(int x) : label(x) {}; * }; */ class Solution { public: /* * @param node: A undirected graph node * @return: A undirected graph node */ UndirectedGraphNode* cloneGraph(UndirectedGraphNode* node) { // write your code here if(node == nullptr) return nullptr; UndirectedGraphNode* res = new UndirectedGraphNode(node->label); node_map[node] = res; _clone(res, node); return res; } void _clone(UndirectedGraphNode* new_point , UndirectedGraphNode* old_point){ if(visited.count(old_point)) return; //检测当前点是否已经被克隆过 visited.insert(old_point); for(auto p:old_point->neighbors){ if(! node_map.count(p)) { //检测当前点是否已经存在(存在映射) UndirectedGraphNode * new_p = new UndirectedGraphNode(p->label); new_point->neighbors.push_back(new_p); node_map[p] = new_p; _clone(new_p, p); }else{ new_point->neighbors.push_back(node_map[p]); _clone(node_map[p],p); } } } private: unordered_map<UndirectedGraphNode*,UndirectedGraphNode*> node_map;//一一对应的节点使用unordered_map unordered_set<UndirectedGraphNode*> visited;//对已经完成过clone的点的标记 };