克隆一张无向图,图中的每个节点包含一个 label
(标签)和一个 neighbors
(邻接点)列表 。
OJ的无向图序列化:
节点被唯一标记。
我们用 #
作为每个节点的分隔符,用 ,
作为节点标签和邻接点的分隔符。
例如,序列化无向图 {0,1,2#1,2#2,2}
。
该图总共有三个节点, 被两个分隔符 #
分为三部分。
- 第一个节点的标签为
0
,存在从节点0
到节点1
和节点2
的两条边。 - 第二个节点的标签为
1
,存在从节点1
到节点2
的一条边。 - 第三个节点的标签为
2
,存在从节点2
到节点2
(本身) 的一条边,从而形成自环。
我们将图形可视化如下:
1 / / 0 --- 2 / \_/
//章节 - 队列和栈 //四、栈和深度优先搜索 //2.克隆图 /* 算法思想: 难点是如何处理每个节点的随机指针,这道题目的难点在于如何处理每个节点的neighbors,由于在深度拷贝每一个节点后,还要将其所有neighbors放到一个vector中,而如何避免重复拷贝呢?这道题好就好在所有节点值不同,所以我们可以使用哈希表来对应节点值和新生成的节点。对于图的遍历的两大基本方法是深度优先搜索DFS和广度优先搜索BFS,这里我们使用深度优先搜索DFS来解答此题, */ //算法实现: /** * Definition for undirected graph. * struct UndirectedGraphNode { * int label; * vector<UndirectedGraphNode *> neighbors; * UndirectedGraphNode(int x) : label(x) {}; * }; */ class Solution { public: UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { unordered_map<int, UndirectedGraphNode*> umap; return clone(node, umap); } UndirectedGraphNode *clone(UndirectedGraphNode *node, unordered_map<int, UndirectedGraphNode*> &umap) { if (!node) return node; if (umap.count(node->label)) return umap[node->label]; UndirectedGraphNode *newNode = new UndirectedGraphNode(node->label); umap[node->label] = newNode; for (int i = 0; i < node->neighbors.size(); ++i) { (newNode->neighbors).push_back(clone(node->neighbors[i], umap)); } return newNode; } };