leetcode : Clone Graph

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
         / \
         \_/
思路:复制图,图的遍历BFS和DFS都可以,但是老图old与新图new的每一个结点是要一一对应的,

可以分两次遍历,第一次遍历生成所有的新结点以及新节点和老结点的对应关系,存储在unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> map里面,

第二次遍历 利用map中对对应关系 将 新图的邻居neighbors赋值,参考:http://blog.csdn.net/lanxu_yy/article/details/17802415

但是可以利用map查看是否已经有了该节点的副本,所以可以不用两次遍历

BFS:当要设置某个结点map[tmpN]的邻居的时候,可以先在map中查看是否存在该邻居的副本nb,有了就这是设置map[tmpN]的邻居为nb的副本,否则就new以nb的副本,再设置,同时要把nb加入需要设置邻居的队列。

/**
 * 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;

        unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> old_new;
        queue<UndirectedGraphNode *> currQ;//存储老的结点,这些老结点已经生成对应新结点了,但是他们的邻居还没处理
        currQ.push(node);
        old_new[node]=new UndirectedGraphNode(node->label);
        while(currQ.size()>0)
        {
            UndirectedGraphNode *tmpN=currQ.front();
            currQ.pop();
            for(auto nb : tmpN->neighbors) //处理tmpN的邻居结点---- old_new[tmpN]->neighbors
            {
                if(old_new.count(nb)==0) // 它的邻居还没生
                {
                    old_new[nb]=new UndirectedGraphNode(nb->label);
                    old_new[tmpN]->neighbors.push_back(old_new[nb]);//添加邻居
                    // nb刚刚拷贝了,但是它的邻居还没处理,所以要加入队列,注意不是新生的结点old_new[nb]加入队列,而是nb加入队列!!
                    currQ.push(nb);
                }
                else
                    old_new[tmpN]->neighbors.push_back(old_new[nb]); //要添加old_new[nb],不是nb,不是nb,不是nb
                
            }
        }
        return old_new[node];
    }
};
DFS:

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */
class Solution {
public:
    UndirectedGraphNode *dfsClone(  UndirectedGraphNode *node,
                                    unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> &old_new)
    {
        if(old_new.count(node)==0)
        {
            old_new[node]=new UndirectedGraphNode(node->label);
            for(auto nb : node->neighbors )
                old_new[node]->neighbors.push_back(dfsClone(nb,old_new));
        }
        return old_new[node];
    }
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) 
    {
        if(node==NULL)    
            return NULL;

        unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> old_new;
        dfsClone(node,old_new);
        return old_new[node];
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值