Clone Graph
Description
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. How we serialize an undirected graph:
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 node 0 to both nodes 1 and 2. Second node is labeled as 1. Connect node 1 to node 2. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle. Visually, the graph looks like the following: 1 / \ / \ 0 --- 2 / \ \_/
Example
return a deep copied graph.
Link
Method
- Use hashmap + vector, search + copy + connect
- Use hashmap + vector, search/copy + connect
- Use hashmap, search + copy + connect
Example
- 1
/** * 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 */ // ------------------------------------------------------------------------- // Version 1. 102ms use the hashmap and vector to solve the problem UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { // write your code here if (!node) { return nullptr; } vector<UndirectedGraphNode*> nodes; unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> map; // find all nodes nodes = nodeSearch(node); // deep copy all nodes int len = nodes.size(); for (int i = 0; i < len; ++i) { map[nodes[i]] = new UndirectedGraphNode(nodes[i]->label); } // connect new nodes for (int i = 0; i < len; ++i) { vector<UndirectedGraphNode*>& oldcons = nodes[i]->neighbors; vector<UndirectedGraphNode*>& newcons = map[nodes[i]]->neighbors; int nlen = oldcons.size(); newcons.resize(nlen); for (int j = 0; j < nlen; ++j) { newcons[j] = map[oldcons[j]]; } } return map[node]; } // modularization/modularize func // bfs : find all unique nodes vector<UndirectedGraphNode*> nodeSearch(UndirectedGraphNode* head) { vector<UndirectedGraphNode*> result; queue<UndirectedGraphNode*> q; unordered_set<UndirectedGraphNode*> hset; q.push(head); hset.insert(head); while (!q.empty()) { UndirectedGraphNode* cur = q.front(); q.pop(); int len = cur->neighbors.size(); for (int i = 0; i < len; ++i) { if (hset.find(cur->neighbors[i]) != hset.end()) { continue; } hset.insert(cur->neighbors[i]); q.push(cur->neighbors[i]); } } // for (auto i = hset.begin(); i != hset.end(); ++i) { // result.push_back(*i); // } for (auto& i : hset) { result.push_back(i); } return result; } // ------------------------------------------------------------------------ // // Version 2, 85ms, All in one UndirectedGraphNode* cloneGraph(UndirectedGraphNode* head) { if (!head) { return nullptr; } unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> map; // search & copy UndirectedGraphNode* cur = nullptr; queue<UndirectedGraphNode*> q; q.push(head); map[head] = new UndirectedGraphNode(head->label); while (!q.empty()) { cur = q.front(); q.pop(); // if (!cur) { // continue; // } int len = cur->neighbors.size(); for (int i = 0; i < len; ++i) { if (cur->neighbors[i] && map.find(cur->neighbors[i]) == map.end()) { q.push(cur->neighbors[i]); map[cur->neighbors[i]] = new UndirectedGraphNode(cur->neighbors[i]->label); } } } // connect for (auto& cur : map) { UndirectedGraphNode* newconn = nullptr; int len = cur.first->neighbors.size(); cur.second->neighbors.resize(len); for (int i = 0; i < len; ++i) { newconn = map.find(cur.first->neighbors[i])->second; cur.second->neighbors[i] = newconn; } } return map.find(head)->second; } // ------------------------------------------------------------------------- // // Version 3, 82ms, trans the ref of hashmap to the whole problem UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { if (!node) { return nullptr; } unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> dict; // vector<UndirectedGraphNode*> nodes; findnodes(dict, node); copynodes(dict); connectnodes(dict); return dict[node]; } void findnodes(unordered_map<UndirectedGraphNode*, UndirectedGraphNode*>& dict, UndirectedGraphNode* node) { queue<UndirectedGraphNode*> q; q.push(node); dict[node] = nullptr; while (!q.empty()) { auto cur = q.front(); q.pop(); // if (dict.find(cur) != dict.end()) { // continue; // } for (auto& neighbor : cur->neighbors) { if (neighbor && dict.find(neighbor) != dict.end()) { continue; } q.push(neighbor); dict[neighbor] = nullptr; } } return; } // copy all unique nodes void copynodes(unordered_map<UndirectedGraphNode*, UndirectedGraphNode*>& dict) { for (auto& nodepair : dict) { if (!nodepair.second) { nodepair.second = new UndirectedGraphNode(nodepair.first->label); } for (auto& neighbor : nodepair.first->neighbors) { if (!dict[neighbor]) { dict[neighbor] = new UndirectedGraphNode(neighbor->label); } } } return; } // connect all unique nodes void connectnodes(unordered_map<UndirectedGraphNode*, UndirectedGraphNode*>& dict) { for (auto& nodepair : dict) { vector<UndirectedGraphNode*>& oldneighbors = nodepair.first->neighbors; vector<UndirectedGraphNode*>& newneighbors = nodepair.second->neighbors; for (auto& neighbor : oldneighbors) { newneighbors.push_back(dict[neighbor]); } } return; } };
Similar problems
x
Tags
x