【问题标题】:Not sure how this recursion works不确定这个递归是如何工作的
【发布时间】:2019-01-30 11:50:16
【问题描述】:
class Solution: 
    def findDuplicateSubtrees(self, root):
        self.res = []
        self.dic = {}
        self.dfs(root)
        return self.res

    def dfs(self, root):
        if not root: return '#'
        tree = self.dfs(root.left) + self.dfs(root.right) + str(root.val)

        if tree in self.dic and self.dic[tree] == 1:
            self.res.append(root)
        self.dic[tree] = self.dic.get(tree, 0) + 1

        return tree

这是在给定二叉树的情况下获取所有重复子树的解决方案。 我不确定tree = self.dfs(root.left) + self.dfs(root.right) + str(root.val) 想要提供什么。

我知道它正在尝试进行后序遍历,但这部分实际上是如何工作的?

如果任何人都可以按照此代码进行操作,那就太好了。谢谢。

【问题讨论】:

    标签: python recursion binary-tree


    【解决方案1】:

    基本上,变量tree可以看作是每个子树的编码字符串。我们使用全局字典self.dic 来记忆那些编码字符串。

    一个例子:

         A
      B      C
    D   D  E   B
              D  D
    

    按层次顺序,二叉树可以描述为[[A], [B, C], [D, D, E, B], [#, #, #, #, #, #, D, D]],所以我们至少有两个重复的子树为[[B], [D, D]][D] 按照代码,我们有

    dfs(A)
      dfs(B)
        dfs(D) *save ##D, return ##D
        dfs(D) *find ##D, get one subtree, return ##D
      *save ##D##DB, return ##D##DB
      dfs(C)
      ...
    

    【讨论】:

      【解决方案2】:

      递归最好从下往上解开。

      • 非节点(叶节点的女儿)将返回 "#"
      • 值为1 的叶子将返回"##1"(因为它有两个非节点子节点)。
      • 具有两个叶女儿12 的节点3 将返回##1##23"##1" 是左女儿的dfs"##2" 是右女儿的dfs"3" 是字符串化的当前节点的值。

      这样,假设没有一个节点的值为23,而另一个节点的值为空字符串,你可以看到如果两个不同的节点产生##1##23,它们就是一个重复的子树。如果使用一些额外的分隔符(例如,该行末尾的分号将产生"##1;##2;3;),它会更加健壮,这足以使其更具可读性和更少歧义。如果使用列表,则更安全(但更慢)。

      【讨论】:

        猜你喜欢
        • 2013-03-20
        • 2016-11-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-25
        • 2017-09-22
        • 2021-01-27
        • 1970-01-01
        • 2011-03-29
        相关资源
        最近更新 更多