Leetcode 133:克隆图(超详细的解法!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/85678360

克隆一张无向图,图中的每个节点包含一个 label (标签)和一个 neighbors (邻接点)列表 。

OJ的无向图序列化:

节点被唯一标记。

我们用 # 作为每个节点的分隔符,用 , 作为节点标签和邻接点的分隔符。

例如,序列化无向图 {0,1,2#1,2#2,2}

该图总共有三个节点, 被两个分隔符 # 分为三部分。

  1. 第一个节点的标签为 0,存在从节点 0 到节点 1 和节点 2 的两条边。
  2. 第二个节点的标签为 1,存在从节点 1 到节点 2 的一条边。
  3. 第三个节点的标签为 2,存在从节点 2 到节点 2 (本身) 的一条边,从而形成自环。

我们将图形可视化如下:

       1
      / \
     /   \
    0 --- 2
         / \
         \_/

解题思路

考察DFSBFS操作,首先使用BFS

class Solution:
    # @param node, a undirected graph node
    # @return a undirected graph node
    def cloneGraph(self, node):
        if not node:
            return None
        
        queue = [node]
        copy_node = UndirectedGraphNode(node.label)
        visited = {node: copy_node}
        while queue:
            node = queue.pop(0)
            for i in node.neighbors:
                if i in visited:
                    visited[node].neighbors.append(visited[i])
                else:
                    copy_node_ne = UndirectedGraphNode(i.label)
                    visited[node].neighbors.append(copy_node_ne)
                    visited[i] = copy_node_ne
                    queue.append(i)
                    
        return copy_node

DFS操作只要将queue换成stack即可。

class Solution:
    # @param node, a undirected graph node
    # @return a undirected graph node
    def cloneGraph(self, node):
        if not node:
            return None
        
        stack = [node]
        copy_node = UndirectedGraphNode(node.label)
        visited = {node: copy_node}
        while stack:
            node = stack.pop()
            for i in node.neighbors:
                if i in visited:
                    visited[node].neighbors.append(visited[i])
                else:
                    copy_node_ne = UndirectedGraphNode(i.label)
                    visited[node].neighbors.append(copy_node_ne)
                    visited[i] = copy_node_ne
                    stack.append(i)
                    
        return copy_node

同样可以快速的写出递归版本的DFS

class Solution:
    # @param node, a undirected graph node
    # @return a undirected graph node
    def cloneGraph(self, node):
        if not node:
            return None
        
        copy_node = UndirectedGraphNode(node.label)
        visited = {node: copy_node}
        self.dfs(node, visited)
        return copy_node
        
    def dfs(self, node, visited):
        for i in node.neighbors:
            if i in visited:
                visited[node].neighbors.append(visited[i])
            else:
                copy_node_ne = UndirectedGraphNode(i.label)
                visited[node].neighbors.append(copy_node_ne)
                visited[i] = copy_node_ne
                self.dfs(i, visited)

一个更好的解法。

class Solution:
    def __init__(self):
        self.visited = dict()
        
    def cloneGraph(self, node):
        if not node:
            return None
        
        if node not in self.visited:
            self.visited[node] = UndirectedGraphNode(node.label)
            for i in node.neighbors:
                self.visited[node].neighbors.append(self.cloneGraph(i))
                
        return self.visited[node]

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/85678360