【问题描述】[中等]


【解答思路】

其实就是深拷贝的一个实现,深拷贝就是对于所有的指针成员,不能仅仅是赋值,还有重新分配空间。

深拷贝反应在本题中就是,所有的结点需要重新new出来,而不是直接赋值。
整体的思路依然是dfs,跑遍原图中每个结点,然后根据原结点生成新结点。
要注意的地方就是,因为图存在环,所以要标记访问过的结点,避免重复形成死循环:
如果该结点已经被访问过,则不再遍历该结点,而是直接将指针值赋给自己邻接点数组----浅拷贝;
如果该结点没有被访问过,则继续dfs遍历该结点,并将产生的新结点----深拷贝;

1. DFS


时间复杂度:O(N) 空间复杂度:O(N)

class Solution {// 哈希表对应关系,节点1 --> 节点1的克隆private HashMap <Node, Node> visited = new HashMap <> ();public Node cloneGraph(Node node) {if (node == null) {return node;}// 如果该节点已经被访问过了,则直接从哈希表中取出对应的克隆节点返回if (visited.containsKey(node)) {return visited.get(node);}// 克隆节点,注意到为了深拷贝我们不会克隆它的邻居的列表Node cloneNode = new Node(node.val, new ArrayList());// 哈希表存储visited.put(node, cloneNode);// 遍历该节点的邻居并更新克隆节点的邻居列表for (Node neighbor: node.neighbors) {cloneNode.neighbors.add(cloneGraph(neighbor));}return cloneNode;}
}
2. BFS

时间复杂度:O(N) 空间复杂度:O(N)

class Solution {public Node cloneGraph(Node node) {if (node == null) {return node;}HashMap<Node, Node> visited = new HashMap();// 将题目给定的节点添加到队列LinkedList<Node> queue = new LinkedList<Node> ();queue.add(node);// 克隆第一个节点并存储到哈希表中visited.put(node, new Node(node.val, new ArrayList()));// 广度优先搜索while (!queue.isEmpty()) {// 取出队列的头节点Node n = queue.remove();// 遍历该节点的邻居for (Node neighbor: n.neighbors) {if (!visited.containsKey(neighbor)) {// 如果没有被访问过,就克隆并存储在哈希表中visited.put(neighbor, new Node(neighbor.val, new ArrayList()));// 将邻居节点加入队列中queue.add(neighbor);}// 更新当前节点的邻居列表//  record.get(n)表示通过原节点得到它的克隆节点// 继续.neighbors.add(record.get(neighbor))表示往它的克隆节点中加入邻接节点// 为什么是add(record.get(neighbor))而不是add(neighbor)// 因为n是原图的节点,record.get(neighbor)才是我们在上面if里克隆出的新节点visited.get(n).neighbors.add(visited.get(neighbor));}}return visited.get(node);}
}

【总结】

1. 课本上总说deep copy和shallow copy,似懂非懂的,不觉得这东西有什么用。慢慢地,发现deep copy背后隐藏的逻辑其实是一种对象图(Object Graph)的遍历行为——这东西广泛出现在各语言的垃圾回收、序列化机制里。内存里各个对象存储空间中放置的引用域/指针就好像有向图里一条边,你沿着它去到达内存中的每个角落、去到当前对象所有的关联对象。题设里的neibours就像一道开胃菜,它可以是其他collection、甚至object,学会这个deep copy,你也就学会了GC里的可达性分析、你也就学会了如何把RAM中的数据固化到硬盘里。
2.读题困难 对HashMap的读取操作不熟悉导致理解困难

转载链接:https://leetcode-cn.com/problems/clone-graph/solution/ke-long-tu-by-leetcode-solution/

[Leetcode][第133题][JAVA][克隆图][DFS][BFS][深拷贝]相关推荐

  1. [Leetcode][第79题][JAVA][单词搜索][DFS][回溯]

    [问题描述][中等] [解答思路] 1. DFS繁琐版本 class Solution {public boolean exist(char[][] board, String word) {bool ...

  2. [Leetcode][第174题][JAVA][地下城游戏][DFS][动态规划]

    [问题描述][中等] [解答思路] 1. 回溯(暴力)& 优化 超时,需要优化 public int calculateMinimumHP(int[][] dungeon) {if (dung ...

  3. [Leetcode][第78题][JAVA][子集][位运算][回溯]

    [问题描述][中等] [解答思路] 1. 位运算 复杂度 class Solution {List<Integer> t = new ArrayList<Integer>(); ...

  4. [Leetcode][第39题][JAVA][组合总和][回溯][dfs][剪枝]

    [问题描述][中等] [解答思路] 1. 回溯 import java.util.ArrayDeque; import java.util.ArrayList; import java.util.De ...

  5. [Leetcode][第889题][JAVA][根据前序和后序遍历构造二叉树][分治][递归]

    [问题描述][中等] [解答思路] copyOfRange class Solution {public TreeNode constructFromPrePost(int[] pre, int[] ...

  6. [Leetcode][第40题][JAVA][数组总和2][回溯][剪枝]

    [问题描述][中等] [解答思路] 1. 减法 import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Ar ...

  7. [Leetcode][第216题][JAVA][数组之和3][回溯]

    [问题描述][中等] [解答思路] 回溯 剪树枝 当和超过n 或 个数超过k 1. 正向求和 优化前 class Solution {public List<List<Integer> ...

  8. [Leetcode][第77题][JAVA][组合][回溯]

    [问题描述][中等] [解答思路] 1. 回溯 class Solution {List<List<Integer>> lists = new ArrayList<> ...

  9. [Leetcode][第17题][JAVA][电话号码的字母组合][回溯]

    [问题描述][中等] [解答思路] 用哈希表/数组存储每个数字对应的所有可能的字母,然后进行回溯操作. 回溯过程中维护一个字符串,表示已有的字母排列(如果未遍历完电话号码的所有数字,则已有的字母排列是 ...

最新文章

  1. NHibernate Step by Step:序篇 (转)
  2. Flutter开发Flutter与原生OC、Java的交互通信-2(48)
  3. 工控随笔_09_西门子_S7-200 Smart与V20 USS通信USS_RPM_R利用轮询的方式通讯异常
  4. python中文解释-python注释和2版本的中文乱码
  5. XGBoost类库使用小结
  6. SAP Hybris Enterprise Commerce Platform ECP架构综述
  7. 算法题存档20190204
  8. linux 架设J2EE网站过程分享之二 —— JDK安装
  9. Entity Framework 4中的Code-First, Model-First和Database-First模式(转)
  10. 小程序模板消息报错41028。解决方法
  11. 弹出消息框并且转向到上/下页
  12. mysqldump 工具使用详解——参数选项
  13. 矩阵分析与应用(二)————梯度分析与最优化
  14. windows编译librtmp
  15. 简单的商品信息管理系统(Java 和sql server数据库)源码
  16. 设置小程序video标签宽高比例为9/16
  17. matplotlib红橙黄绿青蓝紫(含颜色大全)
  18. Django自定义Storage实现图片上传至各大OSS(上篇)
  19. Android 检测输入键盘是否弹起
  20. 时间管理黄金法则分享,让职场的你受益一生

热门文章

  1. caffe源码阅读(1)_整体框架和简介(摘录)
  2. 不同语言,系统通过共享内存方式实现信息交互
  3. SQLServer学习笔记系列4
  4. Java连接SQL数据库失败的分析思路
  5. (运维日志)在win7安装Oracle并部署Oracle数据库
  6. linux火狐浏览器49.0安装教程,火狐浏览器Linux最新版下载
  7. avi和音频合成 ffmpeg_使用Java和ffmpeg把音频和视频合成视频的操作方法
  8. linux下带密码的scp,linux下带密码的scp
  9. 获取所有某格式文件到文件
  10. java搭建tcp客户端_【Java学习笔记】TCP客户端/服务器端