Leetcode:133.克隆图

克隆一张无向图,图中的每个节点包含一个 label (标签)和一个 neighbors (邻接点)列表 。

OJ的无向图序列化:

节点被唯一标记。

我们用 # 作为每个节点的分隔符,用 , 作为节点标签和邻接点的分隔符。

例如,序列化无向图 {0,1,2#1,2#2,2}

该图总共有三个节点, 被两个分隔符  # 分为三部分。 

  1. 第一个节点的标签为 0,存在从节点 0 到节点 1 和节点 2 的两条边。
  2. 第二个节点的标签为 1,存在从节点 1 到节点 2 的一条边。
  3. 第三个节点的标签为 2,存在从节点 2 到节点 2 (本身) 的一条边,从而形成自环。

我们将图形可视化如下:

       1
      / \
     /   \
    0 --- 2
         / \
         \_/

解题思路:

广度优先搜索,映射(unordered_map)。图的克隆,也就是建立一个新的图,使得旧图和新图的结构一致,每个结点存在映射关系,并且对应结点的值相等,并且邻居的值也对应相等。

  1. 建立映射关系,结点与结点的映射。unordered_map<UndirectedGraphNode*, UndirectedGraphNode*>mp;
  2. 设置广度搜索需要的队列,Q,Qc分别对应原图队列以及克隆图队列。
  3. 首先克隆图的第一个结点,*clone=new UndirectedGraphNode(node->label)。建立这两个结点的映射关系mp[node]=clone。
  4. 下一步将克隆node结点的邻居。克隆邻居时会遇到两种情况原图的邻居不能映射到新图,也就意味着,需要创建新的结点然后建立映射关系。或者能找到映射关系,说明这对结点之前访问过。例如,上面访问上图的1时,邻居0能找到映射,因为之前被访问,而邻居2结点不能找到映射。不论之间有没有访问都需要将邻居加入
  5. 加入邻居之后,如果这个结点刚刚才被创建,那么将这对结点分别加入自己的队列。之后将当前访问的结点出队。
  6. 直到队列为空,说明图克隆完毕,return clone。

C++代码
class Solution {
public:
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        if (node == NULL) return NULL;
        queue<UndirectedGraphNode*> Q,Qc;
        UndirectedGraphNode *clone=new UndirectedGraphNode(node->label), *temp,*tempc;
        unordered_map<UndirectedGraphNode*, UndirectedGraphNode*>mp;//两个图的映射
        Q.push(node); Qc.push(clone);
        mp[node] = clone;
        UndirectedGraphNode *p;
        while (!Q.empty()) {
            temp = Q.front();
            tempc = Qc.front();
            int size = temp->neighbors.size();
            for (int i = 1; i <= size; i++) {
                p = temp->neighbors[i - 1];
                if (mp[p] == NULL) {
                    UndirectedGraphNode* newC = new UndirectedGraphNode(p->label);
                    tempc->neighbors.push_back(newC);
                    Q.push(p);
                    Qc.push(newC);
                    mp[p] = newC;
                }
                else {
                    tempc->neighbors.push_back(mp[p]);
                }
            }
            Q.pop();
            Qc.pop();
        }
        return clone;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_23523409/article/details/84633274