133. 克隆图

知识点:图;递归;BFS

题目描述

给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。

图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node])。

class Node {
public int val;
public List<Node> neighbors;
}
示例

输入:adjList = [[2,4],[1,3],[2,4],[1,3]]
输出:[[2,4],[1,3],[2,4],[1,3]]
解释:
图中有 4 个节点。
节点 1 的值是 1,它有两个邻居:节点 2 和 4 。
节点 2 的值是 2,它有两个邻居:节点 1 和 3 。
节点 3 的值是 3,它有两个邻居:节点 2 和 4 。
节点 4 的值是 4,它有两个邻居:节点 1 和 3 。 输入:adjList = [[]]
输出:[[]]
解释:输入包含一个空列表。该图仅仅只有一个值为 1 的节点,它没有任何邻居。 输入:adjList = []
输出:[]
解释:这个图是空的,它不含任何节点。 输入:adjList = [[2],[1]]
输出:[[2],[1]]

解法一:深度优先(DFS)

图的深拷贝是在做什么,对于一张图而言,它的深拷贝即构建一张与原图结构,值均一样的图,但是其中的节点不再是原来图节点的引用。

所以需要进行图的遍历,图的遍历有两种方法:DFS和BFS,为了避免陷入死循环,需要定义一个结构来存储我们已经遍历过的节点,不然从1能到2,到2后又会回到1,所以使用哈希表来存储遍历到的节点,key是遍历到的节点,value是创建的克隆节点,如果遍历过,那直接返回创建的克隆节点。

函数功能:克隆图,其实就是创建节点,然后填充好neighbors。

1.终止条件: node==null, 直接返回node;

2.该做什么:就是创建克隆节点,然后填满邻居节点;所以首先判断有没有在map里,有了的话证明来过了,直接返回克隆的节点就可以,没有的话就创建节点,并且将其放入map中,然后就该填充邻居节点了,递归调用。

3.什么时候做,先创建节点,然后填充调用,先序。

/*
// Definition for a Node.
class Node {
public int val;
public List<Node> neighbors;
public Node() {
val = 0;
neighbors = new ArrayList<Node>();
}
public Node(int _val) {
val = _val;
neighbors = new ArrayList<Node>();
}
public Node(int _val, ArrayList<Node> _neighbors) {
val = _val;
neighbors = _neighbors;
}
}
*/ class Solution {
Map<Node, Node> vis = new HashMap<>();
public Node cloneGraph(Node node) {
if(node == null) return null;
if(vis.containsKey(node)){
return vis.get(node); //访问过了就从表里直接取出克隆的节点;
}
Node cloneNode = new Node(node.val, new ArrayList());
//创建之后放到哈希表里;
vis.put(node, cloneNode);
//遍历邻居并更新;
for(Node neighbor : node.neighbors){
cloneNode.neighbors.add(cloneGraph(neighbor)); //注意邻居节点是克节点;
}
return cloneNode;
}
}

解法二:广度优先(BFS)

和深度一样需要有个map来判断是否遍历过了,使用BFS,创建一个队列,然后将各节点依次入队。入队头节点,然后取出,遍历出队的邻居节点,如果没有被访问过,那就入队,克隆并且添加到map中,如果访问过了,那就更新克隆节点的邻居节点就可以了。

/*
// Definition for a Node.
class Node {
public int val;
public List<Node> neighbors;
public Node() {
val = 0;
neighbors = new ArrayList<Node>();
}
public Node(int _val) {
val = _val;
neighbors = new ArrayList<Node>();
}
public Node(int _val, ArrayList<Node> _neighbors) {
val = _val;
neighbors = _neighbors;
}
}
*/ class Solution {
public Node cloneGraph(Node node) {
Map<Node, Node> vis = new HashMap<>();
if(node == null) return null;
Queue<Node> queue = new LinkedList<>();
queue.add(node); //首节点入队;
vis.put(node, new Node(node.val, new ArrayList())); //克隆节点并入表;
while(!queue.isEmpty()){
Node head = queue.poll();
for(Node neighbor : head.neighbors){
if(!vis.containsKey(neighbor)){
vis.put(neighbor, new Node(neighbor.val, new ArrayList()));
queue.add(neighbor); //依次设置访问过并入队;
}
vis.get(head).neighbors.add(vis.get(neighbor)); //添加邻居,注意是添加的克隆的;
}
}
return vis.get(node);
}
}

相关链接

克隆图

【LeetCode】133. 克隆图的更多相关文章

  1. Java实现 LeetCode 133 克隆图

    133. 克隆图 给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆). 图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node]). class Node { ...

  2. Leetcode 133.克隆图

    克隆图 克隆一张无向图,图中的每个节点包含一个 label (标签)和一个 neighbors (邻接点)列表 . OJ的无向图序列化: 节点被唯一标记. 我们用 # 作为每个节点的分隔符,用 , 作 ...

  3. 【leetcode 133. 克隆图】解题报告

    方法一:dfs(递归) map<Node*,Node*> dict; Node* clone(Node* node) { if (!node) return node; if (dict. ...

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

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

  5. 【LeetCode】克隆图

    [问题]给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆).图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node]). 解释: 节点 的值是 ,它有两个邻居:节点 和 ...

  6. 133克隆图 · Clone Graph

    [抄题]: 克隆一张无向图,图中的每个节点包含一个 label 和一个列表 neighbors. [思维问题]: [一句话思路]: 先BFS克隆点(一个点+扩展所有邻居),再克隆邻居(一个点+扩展所有 ...

  7. C#LeetCode刷题-图

    图篇 # 题名 刷题 通过率 难度 133 克隆图   18.7% 中等 207 课程表   40.0% 中等 210 课程表 II   40.0% 中等 310 最小高度树   29.5% 中等 3 ...

  8. LeetCode 133:克隆图 Clone Graph

    题目: 给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆).图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node]). Given a reference of a ...

  9. leetcode133. 克隆图

    给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆).图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node]).示例: 输入:{"$id":&quo ...

随机推荐

  1. 深入理解Spring的两大特征(IOC和AOP)

    一.spring 的优点? 1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很 ...

  2. 【模拟8.01】matrix(DP杂题,思维题)

    很神的题,感谢lnc大佬的指点. 先设1-LL[i]统称左区间,RR[i]-m为右区间 用L[i]统计从1-i列,出现的左区间端点的前缀和,R[i]是右区间.... f[i][j]中j表示当前在第i列 ...

  3. Linux常用命令详解上

    Linux常用命令详解上 目录 一.shell 二.Linux命令 2.1.内部命令与外部命令的区别 2.2.Linux命令行的格式 2.3.编辑Linux命令行的辅助操作 2.4.获得命令帮助的方法 ...

  4. 手摸手,带你用Beego撸商城系列一(基础篇)

    完整项目地址: go-shop-b2c 系列文章: 手摸手,带你用 Beego撸商城 系列一(基础篇) 手摸手,带你用 Beego撸商城 系列二(登录篇) 手摸手,带你用 Beego撸商城 系列三(系 ...

  5. Redis的flushall/flushdb误操作

    Redis的flushall/flushdb命令可以做数据清除,对于Redis的开发和运维人员有一定帮助,然而一旦误操作,它的破坏性也是很明显的.怎么才能快速恢复数据,让损失达到最小呢? 假设进行fl ...

  6. Redis 雪崩、穿透、击穿、并发、缓存讲解以及解决方案

    1.缓存雪崩 数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机. 比如一个雪崩的简单过程 1.redis集群大面积故障 2.缓存 ...

  7. 使用docker搭建最新版本的gitea,并配置HTTPS访问

    使用docker搭建最新版本的gitea,并配置HTTPS访问 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 简介 之前有搭建 ...

  8. 49、django工程(cookie+session)

    49.1.介绍: 1.cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要"保持状态",因此cookie就是在这样一个场景下诞生. cooki ...

  9. gRPC(3):拦截器

    在 gRPC 调用过程中,我们可以拦截 RPC 的执行,在 RPC 服务执行前或执行后运行一些自定义逻辑,这在某些场景下很有用,例如身份验证.日志等,我们可以在 RPC 服务执行前检查调用方的身份信息 ...

  10. LAMP——实现phpMyadmin、wordpress及Discuz应用部署

    一.环境准备 操作系统:Centos8.3.2011 软件:Apache2.4.37.Mysql8.0.21.PHP7.2.24 二.安装过程 1.安装phpmyadmin 1.1.安装软件包并启动服 ...