Leetcode0133--Clone Graph 克隆无向图
【转载请注明】:https://www.cnblogs.com/igoslly/p/9699791.html
一、题目
二、题目分析
给出一个无向图,其中保证每点之间均有连接,给出原图中的一个点 node,进行图的复制
注意
- 每个点会与多个其他点进行连接,关注节点数据结构,其中 label 表数值,vector 表连接的节点集合
struct UndirectedGraphNode {
int label;
vector<UndirectedGraphNode *> neighbors;
UndirectedGraphNode(int x) : label(x) {};
};
- 图克隆≠图复制,理解浅拷贝 & 深拷贝
- 浅拷贝 ——只是对指针的拷贝,拷贝后两个指针指向同一个内存空间
- 深拷贝 ——不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
- 对于每个节点vector中值,都必须链接到新图的对应节点上
UndirectedGraphNode * newnode = new UndirectedGraphNode (node->label); // 另创结点,深拷贝
unordered_map<UndirectedGraphNode *,UndirectedGraphNode *> hash; // 建立原node → 新node链接
1. 深度优先遍历dfs,采用递归
2. 广度优先遍历bfs
三、代码解析
1、深度优先搜索
- 以 map 记录新旧对应结点
- 若 map 包含结点,直接加入或链接
- 若 map 不包含结点,创建并递归该结点各项内容
class Solution {
public:
// 递归函数
UndirectedGraphNode *clone(UndirectedGraphNode *node,map<UndirectedGraphNode *,UndirectedGraphNode *>& record){
if(!node) return nullptr;
if(record.find(node)!=record.end()){
return record[node];
}else{
UndirectedGraphNode * temp = new UndirectedGraphNode(node->label);
record[node]=temp;
int size = node->neighbors.size();
for(int i=0;i<size;i++){
temp->neighbors.push_back(clone(node->neighbors[i],record));
}
return temp;
}
}
// 主函数
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
map<UndirectedGraphNode *,UndirectedGraphNode *> record;
UndirectedGraphNode * newnode = clone(node,record);
return newnode;
}
};
2、简化后
class Solution {
public:
unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> hash;
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if (!node) return node;
if(hash.find(node) == hash.end()) {
hash[node] = new UndirectedGraphNode(node -> label);
for (auto x : node -> neighbors) {
(hash[node] -> neighbors).push_back( cloneGraph(x) );
}
}
return hash[node];
}
};
2、广度优先搜索
- 以 map 记录新旧对应结点
- 若 map 包含结点,直接加入或链接
- 若 map 不包含结点,加入queue 进行后续操作
class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if(!node) return nullptr;
map<UndirectedGraphNode *,UndirectedGraphNode *> record;
queue<UndirectedGraphNode *> nodelist;
nodelist.push(node);
// 队列循环
while(!nodelist.empty()){
UndirectedGraphNode * temp = nodelist.front();nodelist.pop();
UndirectedGraphNode * newtemp;
// 是否已经被创建
if(record.find(temp)==record.end()){
newtemp = new UndirectedGraphNode(temp->label);
record[temp]=newtemp;
}else{
newtemp = record[temp];
}
int size = temp->neighbors.size();
for(int i=0;i<size;i++){
UndirectedGraphNode * child = temp->neighbors[i];
if(record.find(child)==record.end()){
// 连接结点
UndirectedGraphNode * newchild = new UndirectedGraphNode(child->label);
record[child]=newchild;
nodelist.push(child);
newtemp->neighbors.push_back(newchild);
}else{
newtemp->neighbors.push_back(record[child]);
}
}
}
return record[node];
}
};