【问题标题】:Leetcode 133. Clone Graph with dfs understandingLeetcode 133. 用 dfs 理解 Clone Graph
【发布时间】:2021-06-27 01:31:53
【问题描述】:

您好,我在理解 dfs 时遇到问题。我所知道的是 DFS 有两个版本;我们在通话前和通话后标记访问过。

def solution1(start):
  def dfs1(cur):
    for nei in cur.neighbors:
      if nei not in visited:
        ## mark visit before call
        visited.add(nei)
        dfs1(nei)
  ## drive dfs1
  visited = set()
  visited.add(start)
  dfs1(start)

def solution2(start):
  def dfs2(cur):
    ## mark visit after call
    visited.add(cur)
    for nei in cur.neighbors:
      if nei not in visited:
        dfs2(nei)
  ## drive dfs2
  dfs2(start)

但是,当我将版本 1(调用前已访问的标记)应用于问题 (https://leetcode.com/problems/clone-graph/) 时,它抱怨并且没有复制。

这是我的解决方案:

"""
# Definition for a Node.
class Node:
    def __init__(self, val = 0, neighbors = None):
        self.val = val
        self.neighbors = neighbors if neighbors is not None else []
"""

class Solution:
    """
    def dfs1(cur):
        for nei in cur.neighbors:
            if nei in visited: continue
            visited.add(nei)
            dfs1(nei)
    visited.add(start_node)
    dfs1(start_node)
    """
    def dfs(self, cur, visited):
        
        new_node = Node(cur.val)
        # visited[cur.val] = new_node
        new_neighbors = []
        for nei in cur.neighbors:
            if nei.val not in visited:
                visited[nei.val] = nei
                new_neighbors.append(self.dfs(nei, visited))
            else:
                new_neighbors.append(visited[nei.val])
                
        new_node.neighbors = new_neighbors
        return new_node
        
    def cloneGraph(self, node: 'Node') -> 'Node':
        if node == None:
            return None
        visited = {}
        
        visited[node.val] = node
        return self.dfs(node, visited)

让我知道为什么会出现问题。我不明白为什么它不起作用。

【问题讨论】:

  • 我认为您的代码不起作用的主要原因是因为您将原始节点存储在 visited 字典中。您必须在访问过的节点中存储已处理的 DFS 克隆。为什么?因为在new_neighbors.append(visited[nei.val]) 内部,您将访问节点添加到新克隆节点的邻居。但是任何克隆的节点都应该只有克隆的邻居,而不是原始节点。

标签: python depth-first-search


【解决方案1】:

您的代码不起作用的主要原因是因为您将原始节点存储在 visited 字典中。您必须在visited 中存储节点的已处理 DFS 克隆。为什么?因为在new_neighbors.append(visited[nei.val]) 内部,您将访问节点添加到新克隆节点的邻居。但是任何克隆的节点都应该只有克隆的邻居,而不是原始节点。

我决定使用 DFS 实现我自己的算法/想法版本,LeetCode 系统成功接受下一个代码(所有测试通过):

class Solution:
    def __init__(self):
        self.visited = {}
    def cloneGraph(self, node: 'Node') -> 'Node':
        if node is None:
            return None
        if node.val in self.visited:
            return self.visited[node.val]
        nnode = Node(val = node.val)
        self.visited[nnode.val] = nnode
        nnode.neighbors = [self.cloneGraph(c) for c in node.neighbors]
        return nnode

【讨论】:

    【解决方案2】:

    我们使用哈希映射来创建从原始节点到复制节点的映射。然后我们使用哈希映射来检查我们之前是否访问过该节点。

      def cloneGraph(self,node):  
           # I used closure instead of passing this object
            visited={}
    
            def dfs(node):
                if node in visited:
                    # this returned value will be used inside for loop copy.neighbors.append(dfs(nei))
                    return visited[node]
                #if node is not in visited we add it
                # this is the first part of the copy. first copy the val
                copy=Node(node.val)
                visited[node]=copy
                # we create the neighbors array of "copy" node
                for nei in node.neighbors:
                    copy.neighbors.append(dfs(nei))
                return copy
            return dfs(node) if node else None
    

    【讨论】:

      猜你喜欢
      • 2022-12-11
      • 2020-05-01
      • 2021-09-19
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-10
      相关资源
      最近更新 更多