题目描述
本题要求复制一个无向图,图中每个节点都包含一个标签和它的邻居列表
我们无向图用以下的方法序列化:
- 节点的标签是互不相同的,
- 我们使用“#”作为节点之间的分隔符,使用“,”作为节点标签和节点的节点邻居的分隔符。
例如:现在有一个序列化的无向图{0,1,2#1,2#2,2}.
这个无向图一共有3个节点,因此序列被#分隔成三部分
- 第一个节点的标签是0,节点0和节点1,节点2之间有边
- 第二个节点的标签是1,节点1和节点2之间有边
- 第三个节点的标签是2,节点2和节点2(它自己)之间有边,形成了自环
这个无向图如下图所示
1↵ / ↵ / ↵ 0 --- 2↵ / ↵ \_/↵
思路:
本题考查无向图的深拷贝,想了会没想到什么好思路,还是老老实实编号建表吧…
- 创建一个mp1,用来查找原始图中各个结点的编号;
- 创建一个mp2,用来标记各个编号的新结点的地址;
- 给原始图创建查找表时使用的是深度优先遍历,利用unordered_map的find函数查看是否已经编过号。这样mp1的size()就是这个图的结点个数;
- 遍历mp1,完善新图。
写代码的过程中感觉到了自己对STL的不熟练,很多函数都不确定用法,还要大量的联系来夯实基础。
代码:
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if (node == NULL)
return NULL;
unordered_map<UndirectedGraphNode *, int> mp1;
unordered_map<int, UndirectedGraphNode *> mp2;
DfsGraph(node, mp1, node->label);
for (auto x : mp1)
{
UndirectedGraphNode *tmp = new UndirectedGraphNode(0);
tmp->label = x.second;
mp2.insert(make_pair(tmp->label, tmp));
}
for (auto x : mp1)
{
vector<UndirectedGraphNode *> vec;
for (auto y : x.first->neighbors)
{
vec.push_back(mp2.at(mp1.at(y)));
}
mp2.at(x.second)->neighbors = vec;
}
return mp2.at(mp1.at(node));
}
void DfsGraph(UndirectedGraphNode *node, unordered_map<UndirectedGraphNode *, int> &mp, int index)
{
if (mp.find(node) != mp.end())
return;
mp.insert(make_pair(node, index));
for (auto val : node->neighbors)
DfsGraph(val, mp, val->label);
}
};
大佬们的代码:
class Solution {
public:
Node* cloneGraph(Node* node) {
unordered_map<Node*, Node*> mp;
return dfs(node, mp);
}
Node* dfs(Node* node, unordered_map<Node*, Node*>& mp){
if(!node) return NULL;
if(mp.count(node)) return mp[node];
Node* tmp = new Node(node->val);
mp[node] = tmp;
for(Node* neighbor: node->neighbors){
tmp->neighbors.push_back(dfs(neighbor, mp));
}
return tmp;
}
};