Leetcode0133--Clone Graph 克隆無向圖

【轉載請註明】:http://www.javashuo.com/article/p-ppkasvgw-cp.htmlhtml

1、題目

2、題目分析

給出一個無向圖,其中保證每點之間均有鏈接,給出原圖中的一個點 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函數

3、代碼解析

一、深度優先搜索

  • 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];
    }
};
相關文章
相關標籤/搜索