LeetCode 133 [Clone Graph]

原題

克隆一張無向圖,圖中的每個節點包含一個 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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容