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. SQL进阶系列之12SQL编程方法

    写在前面 KISS -- keep it sweet and simple 表的设计 注意命名的意义 英文字母 + 阿拉伯数字 + 下划线"_" 属性和列 编程的方针 写注释 注意 ...

  2. Python爬虫入门——使用requests爬取python岗位招聘数据

    爬虫目的 使用requests库和BeautifulSoup4库来爬取拉勾网Python相关岗位数据 爬虫工具 使用Requests库发送http请求,然后用BeautifulSoup库解析HTML文 ...

  3. Thinkphp下记录和统计时间(微秒)和内存使用情况

    * 记录和统计时间(微秒)和内存使用情况 * 使用方法: * <code> * G('begin'); // 记录开始标记位 * // ... 区间运行代码 * G('end'); // ...

  4. DT6.0开发之-调用信息评论

    今天在做destoon6.0产品内页开发时候,用到了调取当前信息评论,所以就顺便做下笔记. 调用当前信息的评论代码: <!--{tag("table=destoot_comment&a ...

  5. SparkSQL读写外部数据源-jext文件和table数据源的读写

    object ParquetFileTest { def main(args: Array[String]): Unit = { val spark = SparkSession .builder() ...

  6. fullcalendar + qTip2显示事件详情

    fullcalendar 是一个很优秀的日历插件.qTip2 是一个强大的提示工具.在讲下面的功能之前,需要对fullcalendar 和 qTip2 有些了解,可直接点击下面贴出的2个地址: ful ...

  7. OLED液晶屏幕(3)串口读取文字并分割

    https://blog.csdn.net/iracer/article/details/50334041 String comdata = ""; void setup() { ...

  8. [学习笔记] Miller-Rabin 质数测试

    Miller-Rabin 事先声明,因为菜鸡Hastin知识水平有限就是菜,因此语言可能不是特别规范,仅供理解. step 0 问一个数\(p\)是否为质数,\(p<=10^{18}\). 一个 ...

  9. proc near/far

    proc是定义子程序的伪指令,位置在子程序的开始处,它和endp分别表示子程序定义的开始和结束两者必须成对出现. far是该子程序的属性,决定调用程序和子程序是否在同一代码段如下:为子程序定义及说明, ...

  10. 【UVA11988】破损的键盘

    题目链接 维护一个链表,以及当前位置.head.tail的指针,模拟就行了 #include<iostream> #include<cstring> #include<c ...