Clone Graph

来源:互联网 发布:艾克里里的变声软件 编辑:程序博客网 时间:2024/04/27 23:11

lone 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         / \         \_/

用一个map(unordered_map)保存原始node和新node的对应关系,一旦遍历到一个node发现对应的新node已经建立过,则直接找到并返回,否则建立新的节点,并copy neighbours。

两种遍历方法,BFS和DFS。

1. DFS。

class Solution {public:    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {        if(node == NULL)  return node;                //record the already copied nodes        unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> copied;        dfs(node, copied);        return copied[node];    }        UndirectedGraphNode* dfs(UndirectedGraphNode *original, unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> &copied)    {        if(copied.find(original) != copied.end())            return copied[original];                UndirectedGraphNode *newnode = new UndirectedGraphNode(original->label);        copied[original] = newnode;        for(auto neighbour : original->neighbors)        {            //here we cannot copy the original neighbour to the new adj list            //newnode->neighbors.push_back(neighbour);                        UndirectedGraphNode* newneighbour = dfs(neighbour, copied);            newnode->neighbors.push_back(newneighbour);        }        return newnode;    }};

2. BFS.

class Solution {public:    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {        if(node == NULL)  return node;                //record the already copied nodes        unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> copied;        queue<UndirectedGraphNode*> Q;                UndirectedGraphNode* newcur = new UndirectedGraphNode(node->label);        copied[node] = newcur;        Q.push(node);                while(!Q.empty())        {            UndirectedGraphNode* cur = Q.front();            Q.pop();                            for(auto neighbour : cur->neighbors)            {                UndirectedGraphNode* newneighbour;                if(copied.find(neighbour) != copied.end())                    newneighbour = copied[neighbour];                else                {                    newneighbour = new UndirectedGraphNode(neighbour->label);                    copied[neighbour] = newneighbour;                    Q.push(neighbour);                }                copied[cur]->neighbors.push_back(newneighbour);            }        }                return copied[node];    }};

3. Non-recursive DFS. 

http://blog.csdn.net/starmsg/article/details/39207445  很多细节需要注意。

class Solution {public:    typedef vector<UndirectedGraphNode *>::iterator adj_iter;        UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node)     {        if(node == NULL) return NULL;        unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> visited;        UndirectedGraphNode *newnode = dfs(node, visited);        return newnode;    }        UndirectedGraphNode *dfs(UndirectedGraphNode *node, unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> &visited)    {        UndirectedGraphNode *newnode = new UndirectedGraphNode(node->label);        stack<pair<UndirectedGraphNode*,adj_iter>> stack;        stack.push(make_pair(node, node->neighbors.begin()));        visited[node] = newnode;                while(!stack.empty())        {            UndirectedGraphNode *cur = stack.top().first;            adj_iter iter = stack.top().second;            if(iter != cur->neighbors.end())            {            UndirectedGraphNode *next = *iter;            stack.top().second = ++iter; //be careful about how to change the iterator value                if(visited.find(next) == visited.end())                {                    UndirectedGraphNode *newnext = new UndirectedGraphNode(next->label);                    visited[next] = newnext;                    visited[cur]->neighbors.push_back(newnext);                    stack.push(make_pair(next, next->neighbors.begin()));                }                else                {                    visited[cur]->neighbors.push_back(visited[next]);                }            }            else                stack.pop();        }        return newnode;    }};


0 0
原创粉丝点击