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)