1. 程式人生 > >Leetcode 133:克隆圖(超詳細的解法!!!)

Leetcode 133:克隆圖(超詳細的解法!!!)

克隆一張無向圖,圖中的每個節點包含一個 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

如有問題,希望大家指出!!!