LeetCode 面试经典 150_图_克隆图(90_133_C++_中等)(深度优先:DFS)

LeetCode 面试经典 150_图_克隆图(90_133_C++_中等)

题目描述:

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

图中的每个节点都包含它的值 val(int) 和其邻居的列表(listNode)。

class Node {

public int val;

public List 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,它有两个邻居:节点 2 和 4 。

节点 2 的值是 2,它有两个邻居:节点 1 和 3 。

节点 3 的值是 3,它有两个邻居:节点 2 和 4 。

节点 4 的值是 4,它有两个邻居:节点 1 和 3 。

示例 2:

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

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

提示:

这张图中的节点数在 0, 100 之间。

1 <= Node.val <= 100

每个节点值 Node.val 都是唯一的,

图中没有重复的边,也没有自环。

图是连通图,你可以从给定节点访问到所有节点。

题解:

解题思路:

思路一(深度优先:DFS):

1、深拷贝 克隆出来一个图,需要重新开辟内存空间 来存储原图值的信息。可采用 DFS 遍历原图,将遍历到的结点进行创建和连接(遍历一个结点创建一个克隆结点,在递归返回时进行连接)。需要注意存在环的处理 ,环的处理可采用记录遍历结点 来解决。当一个克隆结点创建过后,需将原结点记录一下,下次再遍历此节点时不再创建(查找创建过的结点使用哈希表)。

2、复杂度分析:

① 时间复杂度:O(N+E),图中有 N 个节点和 E 条边,:对于图中的每个节点,我们会访问一次,并且递归地遍历它的每个邻居。

② 空间复杂度:O(N),使用一个 unordered_map 来存储已经克隆的节点,最多会存储 N 个节点,因此哈希表的空间复杂度为 O(N)。

代码实现

代码实现(思路一(深度优先:DFS)):
cpp 复制代码
class Solution {
private:
    // 记录已经克隆过的节点,避免重复克隆
    unordered_map<Node*, Node*> visited;

public:
    
    // 克隆图的主函数
    Node* cloneGraph(Node* node) {
        // 如果当前节点为空,返回空指针
        if (node == nullptr) return nullptr;

        // 如果当前节点已经被克隆过,直接返回对应的克隆节点(防止在有环或互相连接的图中产生无限递归)
        if (visited.count(node)) {
            return visited[node];
        }

        // 创建一个新的节点,它是当前节点的克隆
        Node* cloneNode = new Node(node->val);

        // 将克隆节点存入 visited 哈希表,以当前节点为键,克隆节点为值
        visited[node] = cloneNode;

        // 遍历当前节点的邻居
        for (auto &neighbor : node->neighbors) {
            // 递归地克隆邻居,并将克隆的邻居添加到当前克隆节点的邻接列表中
            cloneNode->neighbors.emplace_back(cloneGraph(neighbor));
        }
        
        // 返回克隆后的节点
        return cloneNode;
    }
};

LeetCode 面试经典 150_图_克隆图(90_133)原题链接

欢迎大家和我沟通交流(✿◠‿◠)

相关推荐
恋恋西风2 小时前
C++ 理解 std::thread 在单核和多核上的行为差异
开发语言·c++
Brilliantwxx2 小时前
【Linux】 进程(9)程序与进程地址空间(基础+进阶+面试题)
linux·运维·服务器·开发语言·c++
圣保罗的大教堂2 小时前
leetcode 1406. 石子游戏 III 困难
leetcode
BizzZ_3 小时前
C++(22)——类型转换和IO流
开发语言·c++
怕浪猫3 小时前
AI Agent 的安全围栏:DeepSeek Harness 沙箱隔离策略全解析
面试·agent·产品经理
丰锋ff5 小时前
面试问题合集
面试·职场和发展
颜挺锐6 小时前
如何轻松通过性能测试之第四篇:性能测试项目怎么交付?一文讲透九步实施流程(附面试话术 + 实战清单)
面试·职场和发展
青梅味猪大肠6 小时前
【深入浅出C++】为什么虚表指针可以解决菱形继承
开发语言·c++
Lhan.zzZ6 小时前
QML 组件库:VS2022 + Qt 静态库方案
开发语言·c++·qt·visual studio
敲代码的嘎仔6 小时前
28届后端开发-海康威视日常实习一面(已OC)
java·开发语言·后端·面试·海康威视·实习·大厂