1. 程式人生 > >【LeetCode 中等題】62-克隆圖

【LeetCode 中等題】62-克隆圖

題目描述:克隆一張無向圖,圖中的每個節點包含一個 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
         / \
         \_/

解法1。BFS方式,首先用佇列的方式遍歷所有節點,用dic的方式儲存源節點和新節點的對映關係,然後遍歷每個節點,通過鍵值更新鍵值。

# Definition for a undirected graph node
# class UndirectedGraphNode:
#     def __init__(self, x):
#         self.label = x
#         self.neighbors = []

class Solution:
    # @param node, a undirected graph node
    # @return a undirected graph node
    def cloneGraph(self, node):
        if not node:
            return
        dic = {}
        q = [node]
        new_head = UndirectedGraphNode(node.label)
        dic[node] = new_head
        while q:
            cur = q.pop(0)
            for ne in cur.neighbors:
                if ne not in dic:
                    q.append(ne)
                    new_one = UndirectedGraphNode(ne.label)
                    dic[ne] = new_one
                dic[cur].neighbors.append(dic[ne])
        return new_head

解法2。DFS方式,程式碼和BFS很像,只是遞迴呼叫直至最深處最後一個元素,再回溯一個個,最先遍歷的節點的最後被複制完善。

class Solution:
    # @param node, a undirected graph node
    # @return a undirected graph node
    def cloneGraph(self, node):
        if not node:
            return
        dic = {}
        new_head = UndirectedGraphNode(node.label)
        dic[node] = new_head
        self.dfs(node, dic)
        return new_head
    
    def dfs(self, node, dic):
        if not node:
            return
        for ne in node.neighbors:
            if ne not in dic:
                new_one = UndirectedGraphNode(ne.label)
                dic[ne] = new_one
                self.dfs(ne, dic)
            dic[node].neighbors.append(dic[ne])

參考連結:https://www.jianshu.com/p/f4cb4a9e7570