LeetCode Algorithm 133_Clone Graph
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 / \ \_/
Tags:
分析:
首先,这道题目不能直接返回node,因为需要克隆,也就意味着要为所有的节点心分配空间。
其次,分析节点的元素,包括label和neighbors两项,这意味着完成一个节点需要克隆一个int和一个vector<UndirectedGraphNode *>。
我们根据参数中的node提取出其label值,然后用构造方法生成一个节点,这样就完成了一个节点的生成。然后,根据参数中的node提取
其neighbors中的元素,我们只需要把这些元素加入刚生成的节点中,便完成了第一个节点的克隆。
再次,neighbor元素怎么生成呢?同样需要克隆。这样我们就可以总结出递归的思路。
最后,由于克隆要求每个节点只能有一个备份(其实也只能做到一个备份),所以,对于已经有开辟空间的节点,我们只需要返回已经
存在的节点即可。那怎么做到不重复呢?HashMap!只要我们为每个节点开辟一个空间的时候把这个空间指针保存在HashMap中,便可以
通过查找HashMap来确定当前要克隆的节点是否已经存在,不存在再新开辟空间。
c++代码:
1 /** 2 * Definition for undirected graph. 3 * struct UndirectedGraphNode { 4 * int label; 5 * vector<UndirectedGraphNode *> neighbors; 6 * UndirectedGraphNode(int x) : label(x) {}; 7 * }; 8 */ 9 10 11 class Solution { 12 public: 13 UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { 14 //labeled uniquely so label can be used as the key of map 15 map<int, UndirectedGraphNode *> hashTable; 16 return clone(node, hashTable); 17 } 18 UndirectedGraphNode * clone(UndirectedGraphNode *node, map<int, UndirectedGraphNode *> & hashTable){ 19 if(node == NULL){ 20 return NULL; 21 } 22 //表明这个节点已经创建了,所以没有必要重复创建,只要把已经创建的节点返回即可 23 if(hashTable.find(node->label) != hashTable.end()){ 24 return hashTable[node->label]; 25 } 26 //如果没有创建参数中节点,则创建,并添加到hashtable中 27 UndirectedGraphNode * result = new UndirectedGraphNode(node->label); 28 hashTable[node->label] = result; 29 //clone所有的邻节点,并添加到刚clone好的节点的第二个元素vector中 30 for(int i=0; i<node->neighbors.size();i++){ 31 UndirectedGraphNode * newnode = clone(node->neighbors[i], hashTable); 32 result->neighbors.push_back(newnode); 33 } 34 return result; 35 } 36 };