鏈接: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];
}