133. Clone Graph
Clone an undirected graph. Each node in the graph contains a
label
and a list of itsneighbors
.
OJ’s 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#
.
1. First node is labeled as0
. Connect node 0 to both nodes1
and2
.
2. Second node is labeled as1
. Connect node1
to node2
.
3. Third node is labeled as2
. Connect node2
to node2
(itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1
/ \
/ \
0 --- 2
/ \
\_/
题目大意
输入一个图的任意节点,克隆该图,并返回该克隆图。
解题思路
- 创建克隆的graph,然后创建一个新的节点传入输入的节点的label,并将该新的节点作为克隆graph的起点。
- 以输入的节点为起点,使用广度优先搜索,遍历所有的节点。
- 为了避免重复访问点,使用map存储已访问的节点(key部分存储原始graph的节点,value部分存储克隆节点),判断被访问节点是否被已被访问。如果没有被访问过,通过创建新的键值对,克隆的节点。
- 同时,每次不管被访问节点是不是被访问过,都将其push入当前队列头部节点的neighbors。
算法复杂度
O(|V+E|)
代码实现
/**
* 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 == nullptr) { return nullptr; }
vector<UndirectedGraphNode*, UndirectedGraphNode*> visited;
vector<UndirectedGraphNode *>::iterator iter;
UndirectedGraphNode* graph = new UndirectedGraphNode(node->label);
visited[node] = graph;
queue<UndirectedGraphNode*> que;
que.push(node);
// BFS
while (!que.empty()) {
UndirectedGraphNode* u = que.front();
que.pop();
for (iter = u->neighbors.begin(); iter != u->neighbors.end(); iter++) {
// determine whether it has been visited
if (visited.find((*iter)) == visited.end()) {
visited[*iter] = new UndirectedGraphNode((*iter)->label); // clone the label
que.push(*iter);
}
visited[u]->neighbors.push_back(visited[*iter]); // clone the neighbors
}
}
return graph;
}
};