133. Clone Graph
题目描述
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.
OJs undirected graph serialization:Nodes
are labeled uniquely.
We use # as a separator for each node, and,as a separator for node label and each neighbor of the node.As an example, consider the serialized graph{0,1,2# 1,2# 2,2}.The graph has a total of three nodes, and therefore contains three parts as separated by#.First node is labeled as0. Connect node0to both nodes1and2.Second node is labeled as1. Connect node1to node2.Third node is labeled as2. Connect node2to node2(itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1
/ \
/ \
0 --- 2
/ \
\_/
给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆)。图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node])。
提示:
节点数介于 1 到 100 之间。
无向图是一个简单图,这意味着图中没有重复的边,也没有自环。
由于图是无向的,如果节点 p 是节点 q 的邻居,那么节点 q
也必须是节点 p 的邻居。
必须将给定节点的拷贝作为对克隆图的引用返回。
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> neighbors;
Node() {}
Node(int _val, vector<Node*> _neighbors) {
val = _val;
neighbors = _neighbors;
}
};
*/
方法1
DFS
遍历一定是完备的,一定会访问到每一个节点,不会遗漏。
class Solution {
public:
Node* cloneGraph(Node* node) {
if(!node)
return nullptr;
if(m.find(node)!=m.end())
return m[node];
Node *root = new Node(node->val,{});
m[node] = root;
for(Node* neighbor : node->neighbors)
{
(root->neighbors).push_back(cloneGraph(neighbor));
}
return root;
}
private:
//不同于BFS,这里的DFS中的m以及程序顺序的流程逻辑,确保
//节点的连接关系只会出现在第一次复制节点处,因此并不会出现
//重复连接的情况
unordered_map<Node*, Node*> m;
};
方法2
BFS,这个更容易理解一些,可以想象有左右两个图,左图是原图,右图是复制图。可以看做刚开始两个图一个节点都没有,我们是一个节点一个节点地逐渐增加,从无到有,映射m保存是原节点所对应的复制节点,我们增加节点是根据邻接关系加,而对应的邻接关系只需要在对应的复制图上照原样重复即可,对于BFS,扩展节点时确定邻接关系
class Solution {
public:
Node* cloneGraph(Node* node) {
if(!node)
return nullptr;
unordered_map<Node*, Node*> m;
Node* root = new Node(node->val,{});
m[node] = root;//表示现在左右两图只有根节点一个节点
queue<Node*> q;
q.push(node);
while(!q.empty())
{
Node* cur = q.front();
q.pop();
for(auto neighbor : cur->neighbors)
{
if(m.find(neighbor) == m.end())
{
//在图上增加这个节点
m[neighbor] = new Node(neighbor->val,{});
q.push(neighbor);
}
//将原图节点的邻接对应关系在对应的复制节点上
//照原样重复一遍
(m[cur]->neighbors).push_back(m[neighbor]);
}
}
return root;
}
};