【LeetCode】133. 克隆图
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. 克隆图的更多相关文章
- Java实现 LeetCode 133 克隆图
133. 克隆图 给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆). 图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node]). class Node { ...
- Leetcode 133.克隆图
克隆图 克隆一张无向图,图中的每个节点包含一个 label (标签)和一个 neighbors (邻接点)列表 . OJ的无向图序列化: 节点被唯一标记. 我们用 # 作为每个节点的分隔符,用 , 作 ...
- 【leetcode 133. 克隆图】解题报告
方法一:dfs(递归) map<Node*,Node*> dict; Node* clone(Node* node) { if (!node) return node; if (dict. ...
- Leetcode之广度优先搜索(BFS)专题-133. 克隆图(Clone Graph)
Leetcode之广度优先搜索(BFS)专题-133. 克隆图(Clone Graph) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree ...
- 【LeetCode】克隆图
[问题]给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆).图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node]). 解释: 节点 的值是 ,它有两个邻居:节点 和 ...
- 133克隆图 · Clone Graph
[抄题]: 克隆一张无向图,图中的每个节点包含一个 label 和一个列表 neighbors. [思维问题]: [一句话思路]: 先BFS克隆点(一个点+扩展所有邻居),再克隆邻居(一个点+扩展所有 ...
- C#LeetCode刷题-图
图篇 # 题名 刷题 通过率 难度 133 克隆图 18.7% 中等 207 课程表 40.0% 中等 210 课程表 II 40.0% 中等 310 最小高度树 29.5% 中等 3 ...
- LeetCode 133:克隆图 Clone Graph
题目: 给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆).图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node]). Given a reference of a ...
- leetcode133. 克隆图
给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆).图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node]).示例: 输入:{"$id":&quo ...
随机推荐
- Oracle11g RAC详解
升级变化: Oracle10g,高版本都是由低版本升级得到的.要装10.2.0.4,必须先安装database10.2.0.1,然后给这个ORACLE_HOME打补丁p6180189 ...
- Linux 中使用 QT Charts 显示温度传感器
前一篇笔记中实现了QT的Label控件显示CPU的温度,只能显示当前的温度,并不能反映CPU温度的变化情况,现在来实现使用QT Charts的曲线图实现一个实时曲线来显示CPU的温度. 添加对Qt C ...
- 一、JavaSE语言基础之关键字与标示符
1.关键字 所谓关键字指Java中被赋予了特殊含义的单词或字符,Java中常见的关键字共53个,不需要进行记忆,在写代码的过程中会逐渐接触. 2.标示符 标示符,简单来说就是名字:其最大的作用 ...
- Kubernetes之无头服务(headless)
己经看到如何使用服务来提供稳定的ip地址,从而允许客户端连接到支持服务的每个pod (或其他端点).到服务的每个连接都被转发到一个随机选择的pod上.但是如果客户端需要链接到所有的pod呢?如果后端的 ...
- 低代码开发LCDP,Power Apps系列 - 搭建入职选购电脑设备案例
低代码简介 上世纪八十年代,美国就有一些公司和实验室开始了可视化编程的研究,做出了4GL"第四代编程语言",到后来衍生成VPL"Visual Programming La ...
- SpringCloud:eureka的'eurekaAutoServiceRegistration'报错解决方法
报错信息如下: org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with ...
- 第一章 - Java与线程
目录 01.Java和线程 02.Java与协程 03.CPU缓存结构和java内存模型 04.管程-悲观锁和锁优化 05.乐观锁 - 无锁方案 06.线程安全 07.线程池 08.JUC 09.高并 ...
- 自己动手模拟spring的IOC
我们这里是模拟spring,主要模拟spring中的IOC功能,所以在此我们一样要在service层中定义dao的实例,当然不用new出来,我们就通过spring的IOC把这里的dao层注入进来.不要 ...
- mysql 去重的两种方式
1.distinct一般用于获取不重复字段的条数 使用原则: 1)distinct必须放在要查询字段的开头,不能放在查询字段的中间或者后面 select distinct name from user ...
- 南京大学计算机基础 X64函数调用和链接器原理和可重定位的文件.o
一. 1.函数调用差别 X64的函数调用,和X86函数调用区别,在于参数的传递不一样了,X64的参数传递不在依靠栈来传,而是寄存器,不过还是具有局限性的 比如只能允许六个寄存器来传,分别是RDI,RS ...