【问题标题】:Find all paths in a binary tree查找二叉树中的所有路径
【发布时间】:2020-11-24 01:13:52
【问题描述】:

我正在尝试解决“给定二叉树,返回所有从根到叶的路径”的编码问题。

Input:

   1
 /   \
2     3
 \
  5

Output: ["1->2->5", "1->3"]

我见过一种解决方案

class Solution:
    def binaryTreePaths(self, root: TreeNode) -> List[str]:
        allPath = []
        if root is None:
            return []
        self.find_all_paths_recursive(root, [], allPath)
        return allPath

    def find_all_paths_recursive(self, currNode, currPath, allPath):
        if currNode is None:
            return 
        currPath.append(currNode.val)
        if currNode.left is None and currNode.right is None:
            currOut = '->'.join([str(x) for x in list(currPath)])
            allPath.append(currOut)
        # traverse left sub tree
        self.find_all_paths_recursive(currNode.left, currPath, allPath)
        # traverse right sub tree
        self.find_all_paths_recursive(currNode.right, currPath, allPath)
        del currPath[-1]

运行上面的代码给了我["1->2->5", "1->3"]的答案,这是正确的。

我正在考虑将if currNode.left is None and currNode.right is None:下的代码块更改为

      if currNode.left is None and currNode.right is None:
            #currOut = '->'.join([str(x) for x in list(currPath)])
            #allPath.append(currOut)
            allPath.append(currPath)

应该给我结果 [[1,2,5], [1,3]]。但是,此更改为我返回了结果 [[],[]]。我想知道为什么这不起作用?

【问题讨论】:

    标签: python recursion tree


    【解决方案1】:

    由于您想直接添加 currPath,因此您必须在该时刻添加 currPath 的副本。

    像这样:

    if currNode.left is None and currNode.right is None:
        #currOut = '->'.join([str(x) for x in list(currPath)])
        # allPath.append(currOut)
        allPath.append(list(currPath))
    

    编辑:

    如果不添加 list,您会将原始列表对象添加到 allPath,该对象将由于递归而更新。添加list 将生成copy of the original list object,该copy of the original list object 将被保存且不会进一步更新。

    【讨论】:

    • 谢谢,asd asd。你能帮我解释一下为什么不添加列表就行不通吗?
    • 如果不添加列表,您会将原始列表对象添加到将被更新的 allPath。添加 list() 将制作原始列表对象的副本,该副本将被保存并且不会进一步编辑。
    【解决方案2】:

    递归是一种函数式遗产,因此将其与函数式风格一起使用会产生最佳效果。这意味着要避免变量重新分配、其他突变和副作用。

    让我们看看以这种方式实现btree 会是什么样子。注意node 属性leftright 可以在构造新节点时设置-

    # btree.py
    
    def empty():
      return None
    
    class node:
      def __init__(self, val, left = empty(), right = empty()):
        self.val = val
        self.left = left
        self.right = right
    
    def paths(t, p = ()):
      if not t:
        return
      elif t.left or t.right:
        yield from paths(t.left, (*p, t.val))
        yield from paths(t.right, (*p, t.val))
      else:
        yield "->".join(map(str, (*p, t.val)))
    

    这是您现在的main 程序 -

    # main.py
    
    from btree import node, empty, paths
    
    #    1
    #  /   \
    # 2     3
    #  \
    #   5
    
    t = node(1, node(2, empty(), node(5)), node(3))
    
    print(list(paths(t)))
    
    ['1->2->5', '1->3']
    

    【讨论】:

    • 我认为您没有完全理解 OP 的问题。请再读一遍。 (OP 期望 [[1,2,5], [1,3]] 但正在得到 [[], []]. 并想知道为什么会这样)
    • Tibebes,有些问题让我们完全走错了路
    猜你喜欢
    • 2017-08-14
    • 1970-01-01
    • 2017-07-31
    • 2012-12-09
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-16
    相关资源
    最近更新 更多