链接:https://oj.leetcode.com/problems/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 #
.
- First node is labeled as
0
. Connect node0
to both nodes1
and2
. - Second node is labeled as
1
. Connect node1
to node2
. - Third node is labeled as
2
. Connect node2
to node2
(itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1 / \ / \ 0 --- 2 / \ \_/
方法一:
类似前面Random List copy思路,三遍遍历,第一遍针对原始的图中的每一个节点复制一个放在该节点的最后neighbour,第二遍将所有的节点的邻居修改为正确的,最后一遍从原来的图节点剥离新的节点。
超时。
代码如下:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if( node == NULL) return NULL;
UndirectedGraphNode *p = node;
set<UndirectedGraphNode*> visitNode;
queue<UndirectedGraphNode*> q;
q.push(node);
while(!q.empty())
{
p = q.front();
q.pop();
visitNode.insert(p);
vector<UndirectedGraphNode*>::iterator it = p->neighbors.begin();
while( it != p->neighbors.end() )
{
if(visitNode.count(*it) <= 0)
q.push(*it);
it++;
}
UndirectedGraphNode* newNode = new UndirectedGraphNode(p->label);
newNode->neighbors = p->neighbors;
p->neighbors.push_back(newNode);
}
set<UndirectedGraphNode*>::iterator itSet = visitNode.begin();
while( itSet != visitNode.end() )
{
p = (*itSet)->neighbors.back();
vector<UndirectedGraphNode*> newNei;
vector<UndirectedGraphNode*>::iterator itV = p->neighbors.begin();
while( itV != p->neighbors.end() )
{
newNei.push_back((*itV)->neighbors.back());
itV++;
}
p->neighbors = newNei;
itSet++;
}
itSet = visitNode.begin();
UndirectedGraphNode * result = (*itSet)->neighbors.back();
while( itSet != visitNode.end() )
{
(*itSet)->neighbors.pop_back();
itSet++;
}
return result;
}
方法二:
只需要一次遍历,BFS遍历,在每次入栈之前对每一个原图节点新建一个节点,保存新节点和原来节点的关系,在每一次出队列时对新的节点设置neighbous。
借助hash加速。
代码如下:
UndirectedGraphNode* cloneGraphMap(UndirectedGraphNode *node)
{
if( node == NULL) return NULL;
map<UndirectedGraphNode*, UndirectedGraphNode*> nodeMap;
queue<UndirectedGraphNode*> q;
q.push(node);
nodeMap[node] = new UndirectedGraphNode(node->label);
while(!q.empty())
{
UndirectedGraphNode *p = q.front();
q.pop();
UndirectedGraphNode *copy = nodeMap[p];
vector<UndirectedGraphNode*>::iterator it = p->neighbors.begin();
while( it != p->neighbors.end() )
{
if( nodeMap.count(*it) <= 0)
{
nodeMap[*it] = new UndirectedGraphNode((*it)->label);
q.push(*it);
}
copy->neighbors.push_back(nodeMap[*it]);
it++;
}
}
return nodeMap[node];
}