Featured image of post Clone Graph

Clone Graph

133. 克隆图

分析

  1. 哈希表存储原节点与克隆节点的映射:
    • 使用 hash 保存原图节点到克隆节点的映射关系,用于快速找到已克隆的节点,避免重复克隆
  2. DFS 遍历图的所有节点:
    • 对每个未访问过的节点,创建其克隆节点并存入 hash
    • 遍历当前节点的所有邻居,如果邻居未被克隆,则递归处理
  3. 复制邻接关系:
    • 遍历所有节点(已在 hash 中),将每个原节点的邻居对应的克隆节点添加到克隆节点的邻居列表中
  4. 最终返回起始节点的克隆版本,即为完整的深拷贝图

时间复杂度

图的所有节点和边都会被访问一次,因此时间复杂度为 O(N + E),其中 N 是节点数,E 是边数

空间复杂度

递归调用栈的深度取决于图的结构,最坏情况下为 O(N),加上哈希表的存储空间,总体复杂度为 O(N)

C++代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution
{
public:
    Node* cloneGraph(Node* node)
    {
        if (!node)
            return nullptr;

        std::unordered_map<Node*, Node*> hash; // 哈希表存储节点映射
        dfs(node, hash); // 深度优先搜索创建克隆节点

        // 第二次遍历复制邻接关系
        for (auto& [origin, copy] : hash)
            for (Node* neighbor : origin->neighbors)
                copy->neighbors.push_back(hash[neighbor]); // 将原节点的邻接点的克隆节点添加到克隆节点的邻接表中

        return hash[node]; // 返回克隆图的起点
    }

    void dfs(Node* node, std::unordered_map<Node*, Node*>& hash)
    {
        // 克隆当前节点
        hash[node] = new Node(node->val);

        // 递归克隆邻居节点
        for (Node* neighbor : node->neighbors)
            if (hash.count(neighbor) == 0) // 如果邻居未被克隆
                dfs(neighbor, hash); // 递归处理
    }
};
Built with Hugo
Theme Stack designed by Jimmy