通过深度优先遍历的方式进行实现

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

    1. function cloneGraph(node) {
    2. if (!node) return;
    3. const visited = new Map();
    4. const dfs = (n) => {
    5. const newNode = new Node(n.val);
    6. visited.set(n, newNode);
    7. (n.neighbors || []).forEach((next) => {
    8. if (!visited.has(next)) {
    9. dfs(next);
    10. }
    11. newNode.neighbors.push(visited.get(next));
    12. });
    13. };
    14. dfs(node);
    15. return visited.get(node);
    16. }

代码中主要访问了图的所有节点,所以时间复杂度是O (n) n 代表节点数,空间复杂度是O (n) ,因为我们定义了 Map 数据结构,里面用来存放所有节点。

这里可能会有同学问,递归的空间复杂度不是递归的深度吗?不是也要算进去吗?因为递归的深度很大可能性是小于 Map 的长度的,所以我们以空间复杂度最大值为准。

通过广度优先遍历的方式进行实现

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

    1. function cloneGraph(node) {
    2. if (!node) return;
    3. const visited = new Map();
    4. visited.set(node, new Node(node.val));
    5. const q = [node];
    6. while (q.length) {
    7. const n = q.shift();
    8. (n.neighbors || []).forEach((next) => {
    9. if (!visited.has(next)) {
    10. q.push(next);
    11. visited.set(next, new Node(next.val));
    12. }
    13. visited.get(n).neighbors.push(visited.get(next));
    14. });
    15. }
    16. return visited.get(node);
    17. }

首先时间复杂度依然是 O (n)n 代表所有节点数,因为广度优先遍历会访问图的所有节点。空间复杂度为 O (n) 因为我们使用了队列,队列的长度最坏情况下可能是所有的节点数。