首页 > 技术文章 > [LeetCode] Clone Graph

diegodu 2015-06-05 11:22 原文

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 as 0. Connect node 0 to both nodes 1 and 2.
  2. Second node is labeled as 1. Connect node 1 to node 2.
  3. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.

 

Visually, the graph looks like the following:

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

 

 

Hide Tags
 Depth-first Search Breadth-first Search Graph
 
 
 
 
分析:
1 首先看清题目,虽然是无向图,但是只有两个节点之间只存在一条边,没有重复,以途中给的例子看,0 节点包含 到1节点2节点的变,但是1节点中不包含到0节点的边,给我们此题解题带来了方便。
2 去重问题,问题是在clone一个节点时我们需要clone它的neighbors,而邻居节点有的已经存在,有的未存在,如何进行区分?

这里我们使用Map来进行区分,Map的key值为原来的node,value为新clone的node,当发现一个node未在map中时说明这个node还未被clone,

将它clone后放入queue中处理neighbors。

使用Map的主要意义在于充当BFS中Visited数组,它也可以去环问题,例如A--B有条边,当处理完A的邻居node,然后处理B节点邻居node时发现A已经处理过了

处理就结束,不会出现死循环!

3 注意  each node in queue is already copied itself,but neighbors are not copied yet
 
/**
 * 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 == NULL)
                return NULL;

            map <UndirectedGraphNode*, UndirectedGraphNode*> old2New;
            queue <UndirectedGraphNode*> q;

            UndirectedGraphNode* oldNode = NULL;

            // each node in queue is already copied itself
            // but neighbors are not copied yet
            old2New[node] = new UndirectedGraphNode(node->label);
            q.push(node);

            while(!q.empty())
            {
                oldNode = q.front();
                q.pop();

                for(int i = 0; i < oldNode->neighbors.size(); i++)
                {
                    if(oldNode->neighbors[i] != NULL)
                    {
                        if(old2New.count(oldNode->neighbors[i]) != 0)
                        {
                            old2New[oldNode]->neighbors.push_back(old2New[oldNode->neighbors[i]]);
                        }
                        else
                        {
                            UndirectedGraphNode* tmp = new UndirectedGraphNode(oldNode->neighbors[i]->label);
                            old2New[oldNode->neighbors[i]] = tmp;//build the mapping
                            old2New[oldNode]->neighbors.push_back(tmp);

                            // add it to queue after copy it if the node doesn't the map
                            q.push(oldNode->neighbors[i]);
                        }
                    }
                }
            }

            return old2New[node];
        }
};

 

 

推荐阅读