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:

  1. The number of nodes will be between 1 and 100.
  2. The undirected graph is a simple graph, which means no repeated edges and no self-loops in the graph.
  3. Since the graph is undirected, if node p has node q as neighbor, then node q must have node p as neighbor too.
  4. 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;
}
};

类似题目:

Copy List with Random Pointer

参考资料:

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 克隆无向图的更多相关文章

  1. [LeetCode] 133. Clone Graph 克隆无向图

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

  2. [LeetCode] Clone Graph 无向图的复制

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

  3. LeetCode: Clone Graph 解题报告

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

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

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

  5. LeetCode:Clone Graph

    题目如下:实现克隆图的算法  题目链接 Clone an undirected graph. Each node in the graph contains a label and a list of ...

  6. Leetcode0133--Clone Graph 克隆无向图

    [转载请注明]:https://www.cnblogs.com/igoslly/p/9699791.html 一.题目 二.题目分析 给出一个无向图,其中保证每点之间均有连接,给出原图中的一个点 no ...

  7. [leetcode]Clone Graph @ Python

    原题地址:https://oj.leetcode.com/problems/clone-graph/ 题意:实现对一个图的深拷贝. 解题思路:由于遍历一个图有两种方式:bfs和dfs.所以深拷贝一个图 ...

  8. Leetcode之广度优先搜索(BFS)专题-133. 克隆图(Clone Graph)

    Leetcode之广度优先搜索(BFS)专题-133. 克隆图(Clone Graph) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree ...

  9. [Leetcode Week3]Clone Graph

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

随机推荐

  1. JSONObject、JSONArray、Map、JavaBean的相互转换

    1,JSONObject json对象,就是一个键对应一个值,使用的是大括号{ },如:{key:value} 2,JSONArray json数组,使用中括号[ ],只不过数组里面的项也是json键 ...

  2. CouchDB 简单HTTP接口使用说明

    目录 1.简介 2.安装 2.HTTP接口简单使用 2.1.认证接口 2.1.1 Basic Authentication 2.1.2 Cookie Authentication 2.2 创建与删除数 ...

  3. spring boot 搭建

    http://www.ityouknow.com/springboot/2018/06/12/spring-boo-java-simple.html 在http://start.spring.io/下 ...

  4. 【C++】C++中的基本内置类型

    基本数据类型 下面这张表是C++支持的基本数据类型 类型 含义 最小尺寸 bool 布尔 未定义 char 字符 8位 wchar_t 宽字符 16位 char16_t Unicode字符 16位 c ...

  5. .net core 2.0+superui +Dapper.SimpleCRUD+mysql+NLog

    **_ .net core 2.0+superui +Dapper.SimpleCRUD+mysql+NLog _** 前端框架 superui http://www.supermgr.cn/ 1.组 ...

  6. Django-jet自定义菜单

    Django-jet自定义菜单:并且可设置权限.https://jet.readthedocs.io/en/latest/config_file.html#custom-menu

  7. 企业和个人都需要的终极跨平台全端解决方案 UniApp

    相信大家在平时开发过程中都会遇到这两类问题: 很多中小型企业要快速开发一个产品,这个产品至少需要覆盖平台范围为:ios.Android.web/H5.微信/支付宝小程序,那么需要的投入的人力成本.时间 ...

  8. Gradle 离线 安装

    第一步:下载gradle zip 文件 第二步:打开文件夹,例如:C:\Users\Administrator.gradle\wrapper\dists\gradle-3.3-all\55gk2rcm ...

  9. jquery.cookie.js写入的值没有定义

    这个是插件的基本语法,你写的没错,错就错在你肯定是在本地测试的,cookie是基于域名来储存的.意思您要放到测试服务器上或者本地localhost服务器上才会生效.cookie具有不同域名下储存不可共 ...

  10. [HDFS Manual] CH8 HDFS Snapshots

    HDFS Snapshots HDFS Snapshots 1. 概述 1.1 Snapshottable目录 1.2 快照路径 2. 带快照的更新 3. 快照操作 3.1 管理操作 3.2 用户操作 ...