当前位置: 面试刷题>> 克隆图(经典算法150题)


### 题目描述 给定一个无向图,图中的节点由一个唯一的整数ID表示,每个节点都有一个列表,其中包含与该节点直接相连的节点ID。图以字典形式给出,字典的键是节点的ID,字典的值是一个列表,包含与该节点相连的所有节点的ID。 图的表示示例如下(使用Python字典表示): ```python graph = { '1': ['2', '4'], '2': ['1', '3'], '3': ['2'], '4': ['1'] } ``` 图是无向的,意味着如果节点'1'到节点'2'有一条边,那么节点'2'到节点'1'也有一条边。 现在,你的任务是克隆这个图,即创建一个图的深拷贝,使得原图和克隆图在逻辑上是分离的,即修改克隆图中的任何节点或边都不会影响原图。 ### 解题思路 为了克隆这个图,我们需要遵循以下步骤: 1. **初始化**:创建一个空字典来存储克隆图的节点。 2. **遍历原图**:对每个节点,如果它还没有被克隆,则创建一个克隆节点,并将其添加到克隆图的字典中。 3. **构建克隆图的边**:在克隆节点时,同时构建与克隆节点相连的边。由于图的节点可能包含循环引用,我们需要一个方法来跟踪已经访问过的节点,避免无限递归。 ### 示例代码 #### PHP 示例 ```php class GraphNode { public $val; public $neighbors; function __construct($val = 0, $neighbors = []) { $this->val = $val; $this->neighbors = $neighbors; } } function cloneGraph($node) { if ($node == null) return null; $visited = []; function cloneNode($node) use (&$visited) { if ($node == null) return null; if (isset($visited[$node->val])) { return $visited[$node->val]; } $clone = new GraphNode($node->val); $visited[$node->val] = $clone; foreach ($node->neighbors as $neighbor) { $clone->neighbors[] = cloneNode($neighbor); } return $clone; } return cloneNode($node); } ``` #### Python 示例 ```python class GraphNode: def __init__(self, val = 0, neighbors = []): self.val = val self.neighbors = neighbors def cloneGraph(node): if not node: return None visited = {} def clone_node(node): if node in visited: return visited[node] clone = GraphNode(node.val, []) visited[node] = clone for neighbor in node.neighbors: clone.neighbors.append(clone_node(neighbor)) return clone return clone_node(node) ``` #### JavaScript 示例 ```javascript class GraphNode { constructor(val = 0, neighbors = []) { this.val = val; this.neighbors = neighbors; } } function cloneGraph(node) { if (!node) return null; const visited = new Map(); function cloneNode(node) { if (visited.has(node)) { return visited.get(node); } const clone = new GraphNode(node.val); visited.set(node, clone); node.neighbors.forEach(neighbor => { clone.neighbors.push(cloneNode(neighbor)); }); return clone; } return cloneNode(node); } ``` 在以上代码中,我们使用了递归和哈希表(在PHP中是关联数组,Python中是字典,JavaScript中是Map)来跟踪已经访问过的节点,从而避免重复克隆和循环引用问题。
推荐面试题