题目:克隆一个无向图。
输入: node = {{1, 2}, {0}, {0, 2}}
解释:
0
/ \
1 2
/\
\/
输入有三个节点,第0个节点和第1个和第2个节点相连,第1个节点和第0个节点相连,
第2个节点 和第0个、第2个节点相连。
输出:{{1, 2}, {0}, {0, 2}}
解释:输出的结构相同,但是节点不一样。
题目解读:
如图1所示,题目利用二维数组给出图结构,要求是给定一个指向图的node,克隆出node’,使它们结构相同,节点不同。
![](https://i-blog.csdnimg.cn/blog_migrate/3933d8ab35a229dfbe5ae21e2e97e7c5.png)
思路分析:
第一步要先通过二维数组构建图, 第二步通过遍历图进行克隆。
代码实现:
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
struct Node {
vector<Node *> neighbors;
};
Node* BuildGraph(vector<vector<int> >& relationships)
{
vector<Node *> nodes(relationships.size());
for (int i = 0; i < relationships.size(); ++i) {
nodes[i] = new Node();
}
for (int i = 0; i < relationships.size(); ++i) {
for (int j = 0; j < relationships[i].size(); ++j) {
(nodes[i]->neighbors).push_back(nodes[relationships[i][j]]);
}
}
return nodes[0];
}
Node* CloneGraph(Node* node, unordered_map<Node*, Node*>& map)
{
if (map.count(node) > 0) //该节点已克隆
return map[node]; //返回克隆节点
Node * clone = new Node();
map.insert({ node, clone });
for (int i = 0; i < node->neighbors.size(); ++i) {
Node* & neighbor = node->neighbors[i];
clone->neighbors.push_back(CloneGraph(neighbor, map));
}
return clone;
}
Node* CloneGraph(Node* node)
{
unordered_map<Node*, Node*> map; //<原节点,克隆节点>
return CloneGraph(node, map);
}
int main()
{
vector<vector<int> > relationships({ {1,2},{0},{0,2} });
Node* node = BuildGraph(relationships);
cout << CloneGraph(node) << endl;
/*对于内存释放,可以遍历记录每个节点指针到一个向量,再释放*/
return 0;
}
扩展:若为有向图,不需要修改代码即可实现。
总结:遍历模型:1.node 2.edge 3.prior(贪心策略)