LeetCode 133 [Clone Graph]

作者: Jason_Yuan | 来源:发表于2016-07-10 08:56 被阅读403次

    原题

    克隆一张无向图,图中的每个节点包含一个 label 和一个表 neighbors。
    你的程序需要返回一个经过深度拷贝的新图。这个新图和原图具有同样的结构,并且对新图的任何改动不会对原图造成任何影响。

    样例
    比如,序列化图 {0,1,2#1,2#2,2} 共有三个节点, 因此包含两个个分隔符#。
    第一个节点label为0,存在边从节点0链接到节点1和节点2
    第二个节点label为1,存在边从节点1连接到节点2
    第三个节点label为2,存在边从节点2连接到节点2(本身),从而形成自环。

    我们能看到如下的图:

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

    解题思路

    • 首先,要遍历无向图,需要使用Hash Map来当作visited数组,防止重复访问而造成程序中的死循环
    • 遍历图有两种方式 - BFS & DFS,本题均可采用
    • BFS - 使用Queue (prefer)
    • DFS - 递归或者使用Stack,对于DFS,每次clone一个node的时候,就要把它所有的neighbor加入到新clone的node的neighbor中,此时recursivly调用dfs,如果没有visited过 - 新建一个node,否则直接从map中找到返回
    • 在visited数组中,key值为原来的node,value为新clone的node,如果一个node不存在于map中,说明这个node还未被clone,将它clone后放入queue中继续处理neighbors

    完整代码

    # Method 1: BFS
    # Definition for a undirected graph node
    # class UndirectedGraphNode(object):
    #     def __init__(self, x):
    #         self.label = x
    #         self.neighbors = []
    
    import Queue
    
    class Solution(object):
        def __init__(self):
            self.visited = {}
            
        def cloneGraph(self, node):
            """
            :type node: UndirectedGraphNode
            :rtype: UndirectedGraphNode
            """
            if not node:
                return None
                
            newHead = UndirectedGraphNode(node.label)
            self.visited[node] = newHead
            
            myQueue = Queue.Queue()
            myQueue.put(node)
            while myQueue.qsize():
                current = myQueue.get()
                for neighbor in current.neighbors:
                    if neighbor not in self.visited:
                        newNode = UndirectedGraphNode(neighbor.label)
                        self.visited[current].neighbors.append(newNode)
                        self.visited[neighbor] = newNode
                        myQueue.put(neighbor)
                    else: # turn directed graph to undirected graph
                        self.visited[current].neighbors.append(self.visited[neighbor])
                        
            return newHead
    
    # Method 2: DFS
    class Solution(object):
        def cloneGraph(self, node):
            """
            :type node: UndirectedGraphNode
            :rtype: UndirectedGraphNode
            """
            if not node:
                return None
                
            return self.dfs(node, {})
            
        def dfs(self, node, map):
            if node in map:
                return map[node]
            newNode = UndirectedGraphNode(node.label)
            map[node] = newNode
            for neighbor in node.neighbors:
                newNode.neighbors.append(self.dfs(neighbor, map))
                
            return newNode
    

    相关文章

      网友评论

        本文标题:LeetCode 133 [Clone Graph]

        本文链接:https://www.haomeiwen.com/subject/qtldjttx.html