133. 克隆图(中等)

Blind 75 › 133. 克隆图(中等) (第 2 章)
文章工具

题目

给定一个无向连通图中某个节点的引用 node,返回整张图的深拷贝:新图的节点数、节点值、连接关系都和原图一致,但每个节点都是新建对象,新节点之间互相连接,绝不引用原图节点。

每个节点有两个字段:val(整数值)和 neighbors(邻居节点列表)。

为方便描述,下面用邻接表表示输入与输出;实际入参是一个 Node 引用。自造示例:

adjList = [[2,3],[1,3,4],[1,2],[2]] → 返回新图中值为 1 的节点引用。新图仍可用 [[2,3],[1,3,4],[1,2],[2]] 描述,但 4 个节点全部是新建对象:copy1 ≠ node1,且 copy1.neighbors 指向的是 copy2、copy3,而不是原图的 node2、node3。

原节点值原邻居克隆节点克隆邻居
node11node2, node3copy1copy2, copy3
node22node1, node3, node4copy2copy1, copy3, copy4
node33node1, node2copy3copy1, copy2
node44node2copy4copy2

约束:节点数 0 ~ 100;1 ≤ Node.val ≤ 100 且每个值唯一;没有重边,也没有自环;图是连通的;空图时 node 为 null。

思路

一句话:一边遍历原图,一边用哈希表记录「原节点 → 已克隆节点」,克隆过的节点直接复用。

最直白的做法是:遇到一个节点就 new 一个复制品,再递归复制它的每个邻居。这个方向是对的,但直接写会出两类问题:

  • 环会导致死循环。 比如 1 ↔ 2,复制 1 时去复制 2,复制 2 时又去复制 1,永远停不下来。
  • 共享邻居会被重复复制。 如果节点 3 同时是节点 1、2 的邻居,它可能被创建多次,最后得到的新图结构就错了。

关键观察:深拷贝只要求「每个原节点恰好对应一个新节点」,剩下的事情都是把邻居指针接到对应的新节点上。因此只要有一张 原节点 → 新节点 的映射,问题就变成一次普通的图遍历。

映射表同时承担两个作用:判重(每个原节点只克隆一次)和断环(再次遇到同一节点时直接返回它的克隆)。至于遍历顺序,DFS 和 BFS 都可以;核心规则都是:先登记当前节点,再处理邻居。

解法

这里用 DFS 实现:

  1. 若 node 为空,直接返回 null,对应空图。
  2. 若当前原节点已经在映射表中,说明它的克隆已建好,直接返回,避免环和重复创建。
  3. 否则新建一个只复制 val 的节点,并立刻写入映射表。
  4. 遍历当前节点的每个邻居,递归得到「邻居的克隆」,追加到当前克隆节点的 neighbors。
  5. 返回当前克隆节点。

处理上面示例时,映射表从空开始逐步长成:

步骤动作映射表
1克隆 node1node1 → copy1
2克隆 node2node1 → copy1, node2 → copy2
3克隆 node3nod

🔒

本篇为付费内容

您已阅读试读部分,购买后即可解锁全文。

⚠️ 本站内容已做唯一性标记并受版权保护,未经授权禁止转载,侵权必究。

还没有评论,来说两句?

发表评论

欢迎交流技术细节;广告与人身攻击会被删除。

在线咨询