题目概述


解题思路
这道题的主要难点在于两个:
- 建图
- 遍历
这道题依然采用了邻接链表的方式建图,之前我建图采用的方式是:开一个两个维度的数组,第一个维度表示节点的数目,第二个维度表示和每个节点相连的边:
class Edges
{
public:
int weight;
string val;
Edges(int wi, string vi): weight(wi), val(vi){}
};
map<string, int> str2idx;
vector<Edges*> Node[N];
这种表示的缺点在于,每个节点的值不方便直接获取,因为它们都被存放在Edges这个类中。
Leetcode这种建图的方式在访问节点值的时候就更为方便:
class Node
{
public:
int val;
vector<Node *>neighbors;
Node (int vi, vector<Node*> ni)
{
val = vi;
neighbors = ni;
};
};
下一步是遍历图。这里我们采用BFS进行原图遍历,只需维护一个set,用来判断之前的节点是否被访问过即可。每次访问到原图的某个节点,就生成相应的一个节点,然后在克隆图中插入。这样就完成了全图克隆。
方法性能
假设原图含V个节点和E条边,方法的时空复杂度均为O(V +E):

代码示例
class Solution {
public:
unordered_map<Node *, Node *> old2new;
unordered_set<Node *> old_nvis;
Node *getCorresNode(Node *old_n)
{
if(old2new.find(old_n) == old2new.end())
{
Node *new_n = new Node(old_n->val, vector<Node*>());
old2new[old_n] = new_n;
}
return old2new[old_n];
}
Node* cloneGraph(Node* node)
{
if(node == NULL)
return node;
queue<Node *> cur_N;
cur_N.push(node);
while(!cur_N.empty())
{
Node *temp_n = cur_N.front();
cur_N.pop();
if(old_nvis.find(temp_n) == old_nvis.end())
{
old_nvis.insert(temp_n);
Node *new_node = getCorresNode(temp_n);
vector<Node *> neigh = temp_n->neighbors;
for (vector<Node *>::iterator iter = neigh.begin(); iter != neigh.end(); ++iter)
{
cur_N.push(*iter);
Node *tmp_neigh = getCorresNode(*iter);
new_node->neighbors.push_back(tmp_neigh);
}
}
}
return old2new[node];
}
};
这篇博客介绍了如何使用C++实现图的克隆,重点在于邻接链表的建模和BFS遍历。通过创建一个映射存储原图与克隆图节点的关系,并使用一个集合跟踪已访问节点,确保了全图的正确复制。这种方法的时间和空间复杂度都是O(V+E),其中V是节点数,E是边数。

529

被折叠的 条评论
为什么被折叠?



