美文网首页程序员
clone graph(克隆一个图)

clone graph(克隆一个图)

作者: 静水流深ylyang | 来源:发表于2019-01-14 20:36 被阅读0次

    题目描述

    Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

    OJ's undirected graph serialization:

    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#.

    1. First node is labeled as0. Connect node0to both nodes1and2.
    2. Second node is labeled as1. Connect node1to node2.
    3. Third node is labeled as2. Connect node2to node2(itself), thus forming a self-cycle.

    Visually, the graph looks like the following:

    题目大意

    克隆一个无向图。
    图中的每个节点都包含一个标签和一个邻接表。
    无向图序列化:
    节点是唯一标记。
    我们使用作为每个节点的分隔符,并且作为节点标签的分隔符和节点的每个邻居节点。
    例如,考虑序列化图{0,1,2#1,2#2,2}。
    该图总共有三个节点,因此包含三个部分,用#分隔。
    第一个节点标记为0。 将node0连接到节点1和2。
    第二个节点标记为1。 将node1连接到node2。
    第三个节点标记为2。 将node2连接到node2(他自己本身),从而形成自循环。
    在视觉上,图表如下所示:

    思路

    使用了BFS算法;
    算法思想很类似,只是,是将创建节点的过程移动到了处理当前节点的邻接点部分处理了;
    如果当前节点的某个邻接点不存在, 创建他, 如果存在, 直接更新map对应的新的图的部分。

    代码

    法一

    // Definition for undirected graph.
    struct UndirectedGraphNode 
    {
        int label;
        vector<UndirectedGraphNode *> neighbors;
        UndirectedGraphNode(int x) : label(x) {};
    };
    
    class Solution 
    {
    public:
        UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node)
        {
            if (!node) return NULL; // 如果结点为空,直接返回NULL
            // 新的copy的图
            UndirectedGraphNode* copy = new UndirectedGraphNode(node -> label);
            mp[node] = copy; // 保存新旧两个图结点的对应关系
            queue<UndirectedGraphNode*> toVisit;
            toVisit.push(node);
            while (!toVisit.empty())
            {
                UndirectedGraphNode* cur = toVisit.front();
                toVisit.pop();
                // 遍历cur结点的相邻结点
                for (UndirectedGraphNode* neigh : cur -> neighbors)
                {
                    // find();:函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。
                    // end();:返回指向map末尾的迭代器
                    // 如果在map中没有找到neigh
                    if (mp.find(neigh) == mp.end())
                    {
                        // map中没有neigh,就创建它
                        UndirectedGraphNode* neigh_copy = new UndirectedGraphNode(neigh -> label);
                        // 把新旧两个图的对应关系保存
                        mp[neigh] = neigh_copy;
                        // 把neigh结点入队(以便接下来遍历他的相邻结点)
                        toVisit.push(neigh);
                    }
                    // 更新当前cur结点的相邻结点的部分
                    mp[cur] -> neighbors.push_back(mp[neigh]);
                }
            }
            return copy; 
        }
    private:
        // 无序map,键值都是UndirectedGraphNode*指针类型
        unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> mp;
    }
    

    法二

    // 递归的思想来做
    class Solution {
    public:
        UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
            if (!node) return NULL;
            if (mp.find(node) == mp.end()) {
                mp[node] = new UndirectedGraphNode(node -> label);
                for (UndirectedGraphNode* neigh : node -> neighbors)
                    mp[node] -> neighbors.push_back(cloneGraph(neigh));
            }
            return mp[node];
        } 
    private:
        unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> mp;
    };
    

    以上。

    相关文章

      网友评论

        本文标题:clone graph(克隆一个图)

        本文链接:https://www.haomeiwen.com/subject/qrajdqtx.html