[LeetCode] Clone Graph 无向图的复制
Given a reference of a node in a connected undirected graph, return a deep copy (clone) of the graph. Each node in the graph contains a val (int) and a list (List[Node]) of its neighbors.
Example:

Input:
{"$id":"1","neighbors":[{"$id":"2","neighbors":[{"$ref":"1"},{"$id":"3","neighbors":[{"$ref":"2"},{"$id":"4","neighbors":[{"$ref":"3"},{"$ref":"1"}],"val":4}],"val":3}],"val":2},{"$ref":"4"}],"val":1} Explanation:
Node 1's value is 1, and it has two neighbors: Node 2 and 4.
Node 2's value is 2, and it has two neighbors: Node 1 and 3.
Node 3's value is 3, and it has two neighbors: Node 2 and 4.
Node 4's value is 4, and it has two neighbors: Node 1 and 3.
Note:
- The number of nodes will be between 1 and 100.
- The undirected graph is a simple graph, which means no repeated edges and no self-loops in the graph.
- Since the graph is undirected, if node p has node q as neighbor, then node q must have node p as neighbor too.
- You must return the copy of the given node as a reference to the cloned graph.
这道无向图的复制问题和之前的 Copy List with Random Pointer 有些类似,那道题的难点是如何处理每个结点的随机指针,这道题目的难点在于如何处理每个结点的 neighbors,由于在深度拷贝每一个结点后,还要将其所有 neighbors 放到一个 vector 中,而如何避免重复拷贝呢?这道题好就好在所有结点值不同,所以我们可以使用 HashMap 来对应原图中的结点和新生成的克隆图中的结点。对于图的遍历的两大基本方法是深度优先搜索 DFS 和广度优先搜索 BFS,这里我们先使用深度优先搜索DFS来解答此题,在递归函数中,首先判空,然后再看当前的结点是否已经被克隆过了,若在 HashMap 中存在,则直接返回其映射结点。否则就克隆当前结点,并在 HashMap 中建立映射,然后遍历当前结点的所有 neihbor 结点,调用递归函数并且加到克隆结点的 neighbors 数组中即可,代码如下:
解法一:
class Solution {
public:
Node* cloneGraph(Node* node) {
unordered_map<Node*, Node*> m;
return helper(node, m);
}
Node* helper(Node* node, unordered_map<Node*, Node*>& m) {
if (!node) return NULL;
if (m.count(node)) return m[node];
Node *clone = new Node(node->val);
m[node] = clone;
for (Node *neighbor : node->neighbors) {
clone->neighbors.push_back(helper(neighbor, m));
}
return clone;
}
};
我们也可以使用 BFS 来遍历图,使用队列 queue 进行辅助,还是需要一个 HashMap 来建立原图结点和克隆结点之间的映射。先克隆当前结点,然后建立映射,并加入 queue 中,进行 while 循环。在循环中,取出队首结点,遍历其所有 neighbor 结点,若不在 HashMap 中,我们根据 neigbor 结点值克隆一个新 neighbor 结点,建立映射,并且排入 queue 中。然后将 neighbor 结点在 HashMap 中的映射结点加入到克隆结点的 neighbors 数组中即可,参见代码如下:
解法二:
class Solution {
public:
Node* cloneGraph(Node* node) {
if (!node) return NULL;
unordered_map<Node*, Node*> m;
queue<Node*> q{{node}};
Node *clone = new Node(node->val);
m[node] = clone;
while (!q.empty()) {
Node *t = q.front(); q.pop();
for (Node *neighbor : t->neighbors) {
if (!m.count(neighbor)) {
m[neighbor] = new Node(neighbor->val);
q.push(neighbor);
}
m[t]->neighbors.push_back(m[neighbor]);
}
}
return clone;
}
};
类似题目:
参考资料:
https://leetcode.com/problems/clone-graph/
https://leetcode.com/problems/clone-graph/discuss/42313/C%2B%2B-BFSDFS
https://leetcode.com/problems/clone-graph/discuss/42309/Depth-First-Simple-Java-Solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Clone Graph 无向图的复制的更多相关文章
- [LeetCode] Clone Graph 克隆无向图
Given a reference of a node in a connected undirected graph, return a deep copy (clone) of the graph ...
- LeetCode: Clone Graph 解题报告
Clone GraphClone an undirected graph. Each node in the graph contains a label and a list of its neig ...
- LeetCode:Clone Graph
题目如下:实现克隆图的算法 题目链接 Clone an undirected graph. Each node in the graph contains a label and a list of ...
- [leetcode]Clone Graph @ Python
原题地址:https://oj.leetcode.com/problems/clone-graph/ 题意:实现对一个图的深拷贝. 解题思路:由于遍历一个图有两种方式:bfs和dfs.所以深拷贝一个图 ...
- 133. Clone Graph(图的复制)
Given the head of a graph, return a deep copy (clone) of the graph. Each node in the graph contains ...
- [LeetCode]Copy List with Random Pointer &Clone Graph 复杂链表的复制&图的复制
/** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label ...
- Leetcode之广度优先搜索(BFS)专题-133. 克隆图(Clone Graph)
Leetcode之广度优先搜索(BFS)专题-133. 克隆图(Clone Graph) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree ...
- [LeetCode] Number of Connected Components in an Undirected Graph 无向图中的连通区域的个数
Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...
- 【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 ...
随机推荐
- [入门级] visual studio 2010 mvc4开发,用ibatis作为数据库访问媒介(一)
[入门级] visual studio 2010 mvc4开发,用ibatis作为数据库访问媒介(一) Date 周二 06 一月 2015 By 钟谢伟 Tags mvc4 / asp.net 示 ...
- passport源码研究
passport的验证过程主要依赖具体的验证策略来实现的,比较常用的有session策略.local策略和github策略等,验证逻辑都是在这些策略类中定义的.passport模块的定 ...
- Angular2 小贴士 Name
Angular2 正式版已经发布了一个月了,我也是通过各种方式在进行验证是否可以满足我们的需求,今天我就发现了一个问题.现在我们来一起说明一下,这个可能不算是bug,而应该需要我们记住就可以了. 我们 ...
- c#面向对象基础技能——学习笔记(二)基于OOP思想研究对象的【属性】
字段(成员变量): 字段只能从对象中访问实例字段,无法直接从类中访问(换言之,不创建实例就不能访问),可以理解为:字段一般用在内部数据交互使用,当需要为外部提供数据时,(要优先使用自动实现的属性而不是 ...
- php在没有登录的情况下自动跳转到登录页
<?php namespace Home\Controller; use Think\Controller; class BaseController extends Controller{ / ...
- [moka同学笔记]PHPexcel之excel导出和导入
原案例来自http://www.sucaihuo.com/有修改 1.目录结构(文件不用解释,应该都可以看得懂,直接看代码)
- 浅谈为之奋斗过的Set接口
Set接口 Set接口存储一组唯一,无序的对象 HashSet 是Set接口常用的实现类 HashSet允许集合元素值为null 操作数据的方法与List类似 Set接口不存在get()方法 set ...
- Microsoft.CodeAnalysis 入门
1 安装 Microsoft.CodeAnalysis 我这里创建的是WPF的项目,首先再VS2015中用NuGet控制台进行安装 Install-Package Microsoft.CodeAnal ...
- Microsoft Dynamics CRM 2013 Js Odata 查询
实现功能: 在新建记录时,(大区,省区,城市)的值默认为当前用户的值.tips:字段均为lookup类型; function Default_region(){ var fromtype=Xrm. ...
- Android开发案例 - 淘宝商品详情
所有电商APP的商品详情页面几乎都是和淘宝的一模一样(见下图): 采用上下分页的模式 商品基本参数 & 选购参数在上页展示 商品图文详情等其他信息放在下页展示 知识要点 垂直方向的ViewPa ...