zoukankan      html  css  js  c++  java
  • [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
             / 
             \_/
    
    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];
            }
    };
     
  • 相关阅读:
    Redis 之服务器集群配置
    Redis 之持久化(rdb、aof)
    Redis 之消息发布与订阅(publish、subscribe)
    Redis事物及锁的运用
    Redis 之hash集合结构及命令详解
    对Ul下的li标签执行点击事件——如何获取你所点击的标签
    .net 面试题(3)
    SQL Server 系统时间
    分布式内存对象缓存 memcached
    MVC 模板页和布局
  • 原文地址:https://www.cnblogs.com/diegodu/p/4554189.html
Copyright © 2011-2022 走看看