【轉載請註明】:http://www.javashuo.com/article/p-ppkasvgw-cp.htmlhtml
給出一個無向圖,其中保證每點之間均有鏈接,給出原圖中的一個點 node,進行圖的複製node
注意數據結構
- 每一個點會與多個其餘點進行鏈接,關注節點數據結構,其中 label 表數值,vector 錶鏈接的節點集合
struct UndirectedGraphNode { int label; vector<UndirectedGraphNode *> neighbors; UndirectedGraphNode(int x) : label(x) {}; };
- 圖克隆≠圖複製,理解淺拷貝 & 深拷貝
- 淺拷貝 ——只是對指針的拷貝,拷貝後兩個指針指向同一個內存空間
- 深拷貝 ——不但對指針進行拷貝,並且對指針指向的內容進行拷貝,經深拷貝後的指針是指向兩個不一樣地址的指針。
- 對於每一個節點vector中值,都必須連接到新圖的對應節點上
UndirectedGraphNode * newnode = new UndirectedGraphNode (node->label); // 另創結點,深拷貝 unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> hash; // 創建原node → 新node連接
1. 深度優先遍歷dfs,採用遞歸
2. 廣度優先遍歷bfs函數
- 以 map 記錄新舊對應結點
- 若 map 包含結點,直接加入或連接
- 若 map 不包含結點,建立並遞歸該結點各項內容
class Solution { public: // 遞歸函數 UndirectedGraphNode *clone(UndirectedGraphNode *node,map<UndirectedGraphNode *,UndirectedGraphNode *>& record){ if(!node) return nullptr; if(record.find(node)!=record.end()){ return record[node]; }else{ UndirectedGraphNode * temp = new UndirectedGraphNode(node->label); record[node]=temp; int size = node->neighbors.size(); for(int i=0;i<size;i++){ temp->neighbors.push_back(clone(node->neighbors[i],record)); } return temp; } } // 主函數 UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { map<UndirectedGraphNode *,UndirectedGraphNode *> record; UndirectedGraphNode * newnode = clone(node,record); return newnode; } };
class Solution { public: unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> hash; UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { if (!node) return node; if(hash.find(node) == hash.end()) { hash[node] = new UndirectedGraphNode(node -> label); for (auto x : node -> neighbors) { (hash[node] -> neighbors).push_back( cloneGraph(x) ); } } return hash[node]; } };
- 以 map 記錄新舊對應結點
- 若 map 包含結點,直接加入或連接
- 若 map 不包含結點,加入queue 進行後續操做
class Solution { public: UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { if(!node) return nullptr; map<UndirectedGraphNode *,UndirectedGraphNode *> record; queue<UndirectedGraphNode *> nodelist; nodelist.push(node); // 隊列循環 while(!nodelist.empty()){ UndirectedGraphNode * temp = nodelist.front();nodelist.pop(); UndirectedGraphNode * newtemp; // 是否已經被建立 if(record.find(temp)==record.end()){ newtemp = new UndirectedGraphNode(temp->label); record[temp]=newtemp; }else{ newtemp = record[temp]; } int size = temp->neighbors.size(); for(int i=0;i<size;i++){ UndirectedGraphNode * child = temp->neighbors[i]; if(record.find(child)==record.end()){ // 鏈接結點 UndirectedGraphNode * newchild = new UndirectedGraphNode(child->label); record[child]=newchild; nodelist.push(child); newtemp->neighbors.push_back(newchild); }else{ newtemp->neighbors.push_back(record[child]); } } } return record[node]; } };