夯实算法-克隆图

149 阅读2分钟

题目:克隆图

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

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

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

测试用例格式:

简单起见,每个节点的值都和它的索引相同。例如,第一个节点值为 1(val = 1),第二个节点值为 2(val = 2),以此类推。该图在测试用例中使用邻接列表表示。

邻接列表 是用于表示有限图的无序列表的集合。每个列表都描述了图中节点的邻居集。

给定节点将始终是图中的第一个节点(值为 1)。你必须将 给定节点的拷贝 作为对克隆图的引用返回。 示例 1:

输入: adjList = [[2,4],[1,3],[2,4],[1,3]]
输出: [[2,4],[1,3],[2,4],[1,3]]
解释: 图中有 4 个节点。
节点 1 的值是 1,它有两个邻居:节点 24 。
节点 2 的值是 2,它有两个邻居:节点 13 。
节点 3 的值是 3,它有两个邻居:节点 24 。
节点 4 的值是 4,它有两个邻居:节点 13

示例 2:

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

示例 3:

输入: adjList = []
输出: []
解释: 这个图是空的,它不含任何节点。

提示:

  1. 节点数不超过 100 。
  2. 每个节点值 Node.val 都是唯一的,1 <= Node.val <= 100
  3. 无向图是一个简单图,这意味着图中没有重复的边,也没有自环。
  4. 由于图是无向的,如果节点 p 是节点 q 的邻居,那么节点 q 也必须是节点 p 的邻居。
  5. 图是连通图,你可以从给定节点访问到所有节点。

解题思路

搜索, 能用BFS就不要用DFS. 步骤为, 用BFS拿到所有的nodes. 对于所有nodes进行copy nodes. 对于所有nodes进行copy neighbors. 注意, 此题不需要保留层级, 因此不需要while内部的for循环. 是图上的BFS, 需要用set.

  1. Map有两个好处 去重和记录克隆的新节点
  2. 每次从队列中取出一个节点 队列里的节点代表的都是已经放在map里了的
  3. 然后遍历该节点的相邻节点 这个时候做两个处理
  4. 若是该节点已经放在了map里也就是放在了队列里的话 我们就直接添加关系
  5. 否则我们就 新建该节点 存入map和队列里

代码实现

public Node cloneGraph(Node node) {
    if (node == null) return node;
    Queue < Node > queue = new LinkedList < > ();
    queue.offer(node);
    Node root = new Node(node.val);
    Map < Node, Node > map = new HashMap < > ();
    map.put(node, root);
    while (!queue.isEmpty()) {
        Node cur = queue.poll();
        Node h = map.get(cur);
        for (Node tmp: cur.neighbors) {
            if (!map.containsKey(tmp)) {
                queue.add(tmp);
                Node neb = new Node(tmp.val);
                map.put(tmp, neb);
            }
            Node n1 = map.get(tmp);
            h.neighbors.add(n1);
        }
    }
    return map.get(node);
}

运行结果

Snipaste_2023-05-05_23-14-10.png

复杂度分析

  • 空间复杂度:O(n)
  • 时间复杂度:O(n)

掘金(JUEJIN) 一起分享知识, Keep Learning!