Leetcode0133--Clone Graph 克隆无向图

【转载请注明】:https://www.cnblogs.com/igoslly/p/9699791.html

一、题目

二、题目分析

给出一个无向图,其中保证每点之间均有连接,给出原图中的一个点 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

三、代码解析

1、深度优先搜索

  • 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;
    }
};

2、简化后

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];
    }
};

2、广度优先搜索

  • 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];
    }
};
posted @ 2018-09-25 15:37  Arya.Mo  阅读(613)  评论(1编辑  收藏  举报