133. Clone Graph

仅供自己学习

 

思路:

DFS:因为图存在循环的情况,如果对每个点的neighbors进行DFS就会进入死循环,所以需要一个结构进行记录克隆过的点,当访问到克隆过的点就返回这个克隆的节点,所以还需要一个数据结构存储克隆的点。我们使用unordered_map的数据结构,value用于存储克隆得到的点,node作为key,并用于判断是否创建过克隆点的结点。如果该节点没有被克隆过,就以该节点的val创建一个克隆节点,并且循环该节点的neighbors,并每个neighbor作为新的node传入函数,即可以DFS的方式遍历所有结点。

//这里的map.find()函数的作用是查找该元素是否存在,不存在则返回map.end()元素。

代码:

 1 /*
 2 // Definition for a Node.
 3 class Node {
 4 public:
 5     int val;
 6     vector<Node*> neighbors;
 7     Node() {
 8         val = 0;
 9         neighbors = vector<Node*>();
10     }
11     Node(int _val) {
12         val = _val;
13         neighbors = vector<Node*>();
14     }
15     Node(int _val, vector<Node*> _neighbors) {
16         val = _val;
17         neighbors = _neighbors;
18     }
19 };
20 */
21 
22 class Solution {
23 public:
24     unordered_map<Node*,Node*> map;
25     Node* cloneGraph(Node* node) {
26         if(node==NULL) return node;
27         if(map.find(node)!=map.end()) return map[node];
28         Node* clonenode = new Node(node->val);
29         map[node] = clonenode;
30         for(auto& neighbor:node->neighbors){
31             clonenode->neighbors.emplace_back(cloneGraph(neighbor));
32         }
33         return clonenode;
34     }
35 };

 

BFS: BFS也是用一个unordered_map的数据结构存储克隆点,同时用作记录该点是否克隆过。BFS肯定用到了队列,所以创建一个队列q,加入node,进入循环,只要队列非空就循环。获取队列第一个元素temp,遍历他的所有neighbors,如果一个neighbor没有被克隆过,就加入队列并且在map[neighbor] 创建一个克隆点,并且在map[temp]->neighbors中加入正在访问的neighbor的克隆点。

 

代码:

 1 /*
 2 // Definition for a Node.
 3 class Node {
 4 public:
 5     int val;
 6     vector<Node*> neighbors;
 7     Node() {
 8         val = 0;
 9         neighbors = vector<Node*>();
10     }
11     Node(int _val) {
12         val = _val;
13         neighbors = vector<Node*>();
14     }
15     Node(int _val, vector<Node*> _neighbors) {
16         val = _val;
17         neighbors = _neighbors;
18     }
19 };
20 */
21 
22 class Solution {
23 public:
24 
25     Node* cloneGraph(Node* node) {
26         if(node==NULL) return node;
27         unordered_map<Node*,Node*> map;
28         queue<Node*> q;
29         q.push(node);
30         map[node]=new Node(node->val);
31         while(!q.empty()){
32             auto temp =q.front();
33             q.pop();
34             for(auto& neighbor:temp->neighbors){
35                 if(map.find(neighbor)==map.end())
36                 {
37                     q.push(neighbor);
38                     map[neighbor]=new Node(neighbor->val);
39                 }
40                 map[temp]->neighbors.emplace_back(map[neighbor]);
41             }
42         }
43         return map[node];
44     }
45 };

 

还有一种DFS的另一种形式,我们用一个Node* visited的数组存储克隆点与用来记录节点是否被用来克隆过,作用同上面的map结构。其余分析是一样的

代码:

 1 /*
 2 // Definition for a Node.
 3 class Node {
 4 public:
 5     int val;
 6     vector<Node*> neighbors;
 7     Node() {
 8         val = 0;
 9         neighbors = vector<Node*>();
10     }
11     Node(int _val) {
12         val = _val;
13         neighbors = vector<Node*>();
14     }
15     Node(int _val, vector<Node*> _neighbors) {
16         val = _val;
17         neighbors = _neighbors;
18     }
19 };
20 */
21 
22 class Solution {
23 public:
24     Node* visited[101];
25     Node* cloneGraph(Node* node) {
26         if(node==NULL) return node;
27         if(visited[node->val]) return visited[node->val];
28         visited[node->val] = new Node(node->val);
29         for(auto& neighbor:node->neighbors){
30             visited[node->val]->neighbors.push_back(cloneGraph(neighbor));
31         }
32         return visited[node->val];
33         
34     }
35 };

 

既然是deepcopy,python自带了deepcopy函数,不知道是不是能直接用,试了一下提交,结果正确,而且速度还是很快的

 1 """
 2 # Definition for a Node.
 3 class Node:
 4     def __init__(self, val = 0, neighbors = None):
 5         self.val = val
 6         self.neighbors = neighbors if neighbors is not None else []
 7 """
 8 
 9 class Solution:
10     def cloneGraph(self, node: 'Node') -> 'Node':
11         return deepcopy(node)

 

posted @ 2021-02-26 01:40  Mrsdwang  阅读(40)  评论(0编辑  收藏  举报