Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

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 as 0. Connect node 0 to both nodes 1 and 2.
  2. Second node is labeled as 1. Connect node 1 to node 2.
  3. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.

Visually, the graph looks like the following:

       1
/ \
/ \
0 --- 2
/ \
\_/

对图的遍历就是两个经典的方法DFS和BFS,和138. Copy List with Random Pointer思路一样,用一个HashMap记录原图节点和复制图节点间的对应关系,以防止重复建立节点,key存原始值,value存copy的值,用DFS,BFS方法遍历帮助拷贝neighbors的值。和那题的不同在于遍历原图相对比linked list的情况复杂一点。可以用BFS或DFS来遍历原图。而HashMap本身除了记录对应关系外,还有记录原图中每个节点是否已经被visit的功能。

Java: DFS

public class Solution {
private HashMap<Integer, UndirectedGraphNode> map = new HashMap<>();
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
return clone(node);
} private UndirectedGraphNode clone(UndirectedGraphNode node) {
if (node == null) return null; if (map.containsKey(node.label)) {
return map.get(node.label);
}
UndirectedGraphNode clone = new UndirectedGraphNode(node.label);
map.put(clone.label, clone);
for (UndirectedGraphNode neighbor : node.neighbors) {
clone.neighbors.add(clone(neighbor));
}
return clone;
}
} 

Java: BFS

/**
* Definition for undirected graph.
* class UndirectedGraphNode {
* int label;
* ArrayList<UndirectedGraphNode> neighbors;
* UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
* };
*/
public class Solution {
/**
* @param node: A undirected graph node
* @return: A undirected graph node
*/
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
if(node == null)
return null; HashMap<UndirectedGraphNode, UndirectedGraphNode> hm = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
LinkedList<UndirectedGraphNode> stack = new LinkedList<UndirectedGraphNode>();
UndirectedGraphNode head = new UndirectedGraphNode(node.label);
hm.put(node, head);
stack.push(node); while(!stack.isEmpty()){
UndirectedGraphNode curnode = stack.pop();
for(UndirectedGraphNode aneighbor: curnode.neighbors){//check each neighbor
if(!hm.containsKey(aneighbor)){//if not visited,then push to stack
stack.push(aneighbor);
UndirectedGraphNode newneighbor = new UndirectedGraphNode(aneighbor.label);
hm.put(aneighbor, newneighbor);
} hm.get(curnode).neighbors.add(hm.get(aneighbor));
}
} return head;
}
}

Java: BFS

/**
* Definition for undirected graph.
* class UndirectedGraphNode {
* int label;
* ArrayList<UndirectedGraphNode> neighbors;
* UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
* };
*/
public class Solution {
/**
* @param node: A undirected graph node
* @return: A undirected graph node
*/
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
if (node == null) {
return null;
}
HashMap<UndirectedGraphNode, UndirectedGraphNode> hm = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
LinkedList<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
UndirectedGraphNode head = new UndirectedGraphNode(node.label);
hm.put(node, head);
queue.add(node); while (!queue.isEmpty()) {
UndirectedGraphNode currentNode = queue.remove();
for (UndirectedGraphNode neighbor : currentNode.neighbors) {
if (!hm.containsKey(neighbor)) {
queue.add(neighbor);
UndirectedGraphNode newNeighbor = new UndirectedGraphNode(neighbor.label);
hm.put(neighbor, newNeighbor);
}
hm.get(currentNode).neighbors.add(hm.get(neighbor));
}
} return head;
}
}

Python: DFS

class UndirectedGraphNode:
def __init__(self, x):
self.label = x
self.neighbors = [] class Solution:
def cloneGraph(self, node):
def dfs(input, map):
if input in map:
return map[input]
output = UndirectedGraphNode(input.label)
map[input] = output
for neighbor in input.neighbors:
output.neighbors.append(dfs(neighbor, map))
return output if node == None: return None
return dfs(node, {})

Python: BFS

class UndirectedGraphNode:
def __init__(self, x):
self.label = x
self.neighbors = [] class Solution:
# @param node, a undirected graph node
# @return a undirected graph node
def cloneGraph(self, node):
if node is None:
return None
cloned_node = UndirectedGraphNode(node.label)
cloned, queue = {node:cloned_node}, [node] while queue:
current = queue.pop()
for neighbor in current.neighbors:
if neighbor not in cloned:
queue.append(neighbor)
cloned_neighbor = UndirectedGraphNode(neighbor.label)
cloned[neighbor] = cloned_neighbor
cloned[current].neighbors.append(cloned[neighbor])
return cloned[node]

C++:DFS

class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if(!node) return NULL;
unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> ht;
stack<UndirectedGraphNode*> s;
s.push(node);
ht[node] = new UndirectedGraphNode(node->label); while(!s.empty()) {
UndirectedGraphNode *p1 = s.top(), *p2 = ht[p1];
s.pop(); for(int i=0; i<p1->neighbors.size(); i++) {
UndirectedGraphNode *nb = p1->neighbors[i];
if(ht.count(nb)) {
p2->neighbors.push_back(ht[nb]);
}
else {
UndirectedGraphNode *temp = new UndirectedGraphNode(nb->label);
p2->neighbors.push_back(temp);
ht[nb] = temp;
s.push(nb);
}
}
} return ht[node];
}
};

C++: BFS

class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if(!node) return NULL;
UndirectedGraphNode *p1 = node;
UndirectedGraphNode *p2 = new UndirectedGraphNode(node->label);
unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> ht;
queue<UndirectedGraphNode*> q;
q.push(node);
ht[node] = p2; while(!q.empty()) {
p1 = q.front();
p2 = ht[p1];
q.pop();
for(int i=0; i<p1->neighbors.size(); i++) {
UndirectedGraphNode *nb = p1->neighbors[i];
if(ht.count(nb)) {
p2->neighbors.push_back(ht[nb]);
}
else {
UndirectedGraphNode *temp = new UndirectedGraphNode(nb->label);
p2->neighbors.push_back(temp);
ht[nb] = temp;
q.push(nb);
}
}
} return ht[node];
}
};

相似题目:

[LeetCode] 138. Copy List with Random Pointer 拷贝带随机指针的链表

All LeetCode Questions List 题目汇总

  

  

[LeetCode] 133. Clone Graph 克隆无向图的更多相关文章

  1. [leetcode]133. Clone Graph 克隆图

    题目 给定一个无向图的节点,克隆能克隆的一切 思路 1--2 | 3--5 以上图为例, node    neighbor 1         2, 3 2         1 3         1 ...

  2. [LeetCode] Clone Graph 克隆无向图

    Given a reference of a node in a connected undirected graph, return a deep copy (clone) of the graph ...

  3. leetcode 133. Clone Graph ----- java

    Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...

  4. Java for LeetCode 133 Clone Graph

    Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...

  5. Leetcode#133 Clone Graph

    原题地址 方法I,DFS 一边遍历一边复制 借助辅助map保存已经复制好了的节点 对于原图中每个节点,如果已经复制过了,直接返回新节点的地址,如果没复制过,则复制并加入map中,接着依次递归复制其兄弟 ...

  6. 133. Clone Graph 138. Copy List with Random Pointer 拷贝图和链表

    133. Clone Graph Clone an undirected graph. Each node in the graph contains a label and a list of it ...

  7. 【LeetCode】133. Clone Graph (3 solutions)

    Clone Graph Clone an undirected graph. Each node in the graph contains a label and a list of its nei ...

  8. [Leetcode Week3]Clone Graph

    Clone Graph题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/clone-graph/description/ Description Clon ...

  9. 133. Clone Graph (3 solutions)——无向无环图复制

    Clone Graph Clone an undirected graph. Each node in the graph contains a label and a list of its nei ...

随机推荐

  1. 逆向破解之160个CrackMe —— 008-009

    CrackMe —— 008 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...

  2. 在命令行中执行kms命令激活Microsoft Office 2010

    激活office2010的命令是什么?激活office2010除了使用office2010激活工具之外,还可以使用kms命令来激活office2010,但是office2010激活命令还需考虑32位或 ...

  3. linux中>/dev/null 2>&1和2>&1 > /dev/null

    转载:https://www.cnblogs.com/520playboy/p/6275022.html 背景 我们经常能在shell脚本中发现>/dev/null 2>&1这样的 ...

  4. janusgraph-遍历图的语言

    精确查询 语句含义 测试语句 执行时间 查询顶点标签为FALV的顶点数量 g.V().hasLabel('FALV').count() 2400s 查询顶点属性中id为19012201 clockWi ...

  5. 四行公式推完神经网络BP

    据说多推推公式可以防止老年痴呆,(●ˇ∀ˇ●) 偶尔翻到我N年前第一次推导神经网络的博客居然四页纸,感慨毅力! http://blog.sina.com.cn/s/blog_1442877660102 ...

  6. 吉首大学2019年程序设计竞赛(重现赛)D - 数列求和(嘤雄难度)

    链接:https://ac.nowcoder.com/acm/contest/992/D $a_{i}=\dfrac {3a_{i-1}-a_{i-2}}{2}+i+1$ 移项再化一下 $a_{i}- ...

  7. Linear Discriminant Analysis Algorithm

    线性判别分析算法. 逻辑回归是一种分类算法,传统上仅限于两类分类问题. 如果有两个以上的类,那么线性判别分析算法是首选的线性分类技术.LDA的表示非常直接.它包括数据的统计属性,为每个类计算.对于单个 ...

  8. fibnacci数列递归实现

    斐波那契数列 Fibonacci sequence又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为"兔子数列" ...

  9. 处理kubernetes 一些比较难删除的资源

    kubernetes 提供了force 的命令在我们删除资源的时候,但是很多时候还是不可以的 一般删除资源的处理 命令 kubectl delete <resource> <reso ...

  10. Mysql 多表连接查询 inner join 和 outer join 的使用

    JOIN的含义就如英文单词“join”一样,连接两张表,大致分为内连接,外连接,右连接,左连接,自然连接.这里描述先甩出一张用烂了的图,然后插入测试数据. 首先先列举本篇用到的分类(内连接,外连接,交 ...