思路就是用一个hashmap维护原图和克隆图之间的节点关系。用BFS从原图的给入节点node展开,每次检查其neighbor节点,若已经在hashmap中,则不需要克隆新节点和新边,只需将这个neighbor节点入queue即可。若该neighbor节点不在hashmap中,则克隆新节点和新边,当然这个旧neighbor节点还是要入queue。
代码如下:
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
/*
* @param node: A undirected graph node
* @return: A undirected graph node
*/
UndirectedGraphNode* cloneGraph(UndirectedGraphNode* node) {
if (!node)
return NULL;
UndirectedGraphNode * p1 = node;
UndirectedGraphNode *p2 = new UndirectedGraphNode(node->label);
//hashmap stores the mirror copy relationship between the original graph and the cloned graph.
map<UndirectedGraphNode *, UndirectedGraphNode *> hashmap;
hashmap[p1]=p2;
queue<UndirectedGraphNode *> q;
q.push(p1);
while(!q.empty()) {
p1=q.front();
q.pop();
p2=hashmap[p1];
for (int i=0; i<p1->neighbors.size(); ++i) {
UndirectedGraphNode * pNode=p1->neighbors[i];
if (hashmap.count(pNode)>0) { //important here!!!
// If pNode is already in hashmap, then its counterpart in the clone graph already exists. We just
// need to add the edge.
p2->neighbors.push_back(hashmap[pNode]); //do not push_back(pNode) as pNode is from the old graph.
//do not push pNode into q here as it has been queued before!
} else {
// If pNode is not in hashmap, it shows its counterpart in the clone graph does not exist. We need
// to create the node first, then add the edge.
UndirectedGraphNode* tempNode = new UndirectedGraphNode(pNode->label);
hashmap[pNode]=tempNode; //stores the mirror relationship between pNode and tempNode;
p2->neighbors.push_back(tempNode); //here we can push_back(tempNode) as it is from the cloned graph.
q.push(pNode); //push pNode into queue.
}
}
}
return hashmap[node];
}
};
二刷:
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
/**
* @param node: A undirected graph node
* @return: A undirected graph node
*/
UndirectedGraphNode* cloneGraph(UndirectedGraphNode *node) {
if (node == nullptr) return nullptr;
map<UndirectedGraphNode *, UndirectedGraphNode*> mp;
queue<UndirectedGraphNode *> q;
q.push(node);
mp[node] = new UndirectedGraphNode(node->label);
while(!q.empty()) {
UndirectedGraphNode * frontNode = q.front();
q.pop();
for (auto neighbor : frontNode->neighbors) {
if (mp.find(neighbor) == mp.end()) {
mp[neighbor] = new UndirectedGraphNode(neighbor->label);
//mp[frontNode]->neighbors.push_back(mp[neighbor]);
q.push(neighbor);
}
mp[frontNode]->neighbors.push_back(mp[neighbor]); //注意,不管frontNode是否在map中出现过,都要复制它的neighbor关系。
}
}
return mp[node];
}
};
三刷:
class Solution {
public:
/**
* @param node: A undirected graph node
* @return: A undirected graph node
*/
UndirectedGraphNode* cloneGraph(UndirectedGraphNode *node) {
if (!node) return NULL;
queue<UndirectedGraphNode *> q;
q.push(node);
orig2New[node] = new UndirectedGraphNode(node->label);
while (!q.empty()) {
UndirectedGraphNode *frontNode = q.front();
q.pop();
for (auto neighbor : frontNode->neighbors) {
if (orig2New.find(neighbor) == orig2New.end()) {
UndirectedGraphNode* newNeighbor = new UndirectedGraphNode(neighbor->label);
orig2New[neighbor] = newNeighbor;
q.push(neighbor); //注意q.push() 要放到if()里面,也就是这个neighbor之前没有被处理过。
}
orig2New[frontNode]->neighbors.push_back(orig2New[neighbor]);
}
}
return orig2New[node];
}
private:
map<UndirectedGraphNode *, UndirectedGraphNode *> orig2New;
};
解法2:DFS
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
/**
* @param node: A undirected graph node
* @return: A undirected graph node
*/
UndirectedGraphNode* cloneGraph(UndirectedGraphNode *node) {
if (node == nullptr) return nullptr;
if (mp.find(node) != mp.end()) return mp[node];
mp[node] = new UndirectedGraphNode(node->label);
for (auto neighbor : node->neighbors) {
mp[node]->neighbors.push_back(cloneGraph(neighbor));
}
return mp[node];
}
private:
map<UndirectedGraphNode *, UndirectedGraphNode*> mp;
};
二刷:
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
/**
* @param node: A undirected graph node
* @return: A undirected graph node
*/
UndirectedGraphNode* cloneGraph(UndirectedGraphNode *node) {
if (!node) return NULL;
if (orig2New.find(node) == orig2New.end()) {
UndirectedGraphNode *newNode = new UndirectedGraphNode(node->label);
orig2New[node] = newNode;
}
for (auto pNeighbor : node->neighbors) {
if (orig2New.find(pNeighbor) == orig2New.end()) {
UndirectedGraphNode *pNewNeighbor = cloneGraph(pNeighbor);
orig2New[pNeighbor] = pNewNeighbor;
}
orig2New[node]->neighbors.push_back(orig2New[pNeighbor]);
}
return orig2New[node];
}
private:
map<UndirectedGraphNode *, UndirectedGraphNode *> orig2New;
};