Python 不知道这个递归是如何工作的

Python 不知道这个递归是如何工作的,python,recursion,binary-tree,Python,Recursion,Binary Tree,这是一个解决方案,用于获取给定二叉树的所有重复子树。 我不确定tree=self.dfs(root.left)+self.dfs(root.right)+str(root.val)试图给出什么 我知道它试图进行后序遍历,但这部分实际上是如何工作的 如果任何人都能遵循此代码,那就太好了。谢谢。递归最好自下而上解决 非节点(叶节点的子节点)将返回“#” 值为1的叶将返回“##1”(因为它有两个非节点子节点) 具有两个叶子节点1和2的节点3将返回##1#23“##1”是左子节点的dfs,“#2”是右

这是一个解决方案,用于获取给定二叉树的所有重复子树。 我不确定tree=self.dfs(root.left)+self.dfs(root.right)+str(root.val)试图给出什么

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


如果任何人都能遵循此代码,那就太好了。谢谢。

递归最好自下而上解决

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

这样,假设没有值为
23
的节点和另一个值为空字符串的节点,您可以看到,如果两个不同的节点生成
##1##23
,则它们是重复的子树。如果使用了一些额外的分隔符(例如,该行末尾的分号将产生
“##1;#2;3;
),这将足够使它更具可读性和不那么模糊。如果使用列表,则更安全(但更慢)。

递归最好从下到上解开

  • 非节点(叶节点的子节点)将返回
    “#”
  • 值为
    1
    的叶将返回
    “##1”
    (因为它有两个非节点子节点)
  • 一个节点有两个叶子子节点
    3
    1
    2
    将返回
    #1#23
    ,“#1”是左子节点的
    dfs
    是右子节点的
    dfs
    是右子节点的
    dfs
    ,而
    是当前节点的值

通过这种方式,假设没有值为
23
的节点和另一个值为空字符串的节点,您可以看到,如果两个不同的节点生成
##1##23
,它们是一个重复的子树。如果使用一些额外的分隔符(例如,该行末尾的分号将生成
),则会更加健壮。”##1、 ##2;3;
),这将足以使它更具可读性,不那么模棱两可。如果使用列表,则更安全(但速度较慢)。

基本上,变量
树可以被视为每个子树的编码字符串。我们使用全局dict
self.dic
来记忆这些编码字符串

例如:

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
按照级别顺序,二叉树可以描述为
[[A]、[B、C]、[D、D、E、B]、#、#、#、#、#、#、D、D]
,因此我们至少有两个重复的子树作为
[[B]、[D、D]
[D]
按照代码,我们有

     A
  B      C
D   D  E   B
          D  D

基本上,变量
tree
可以被视为每个子树的编码字符串。我们使用全局dict
self.dic
来记忆这些编码字符串

例如:

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
按照级别顺序,二叉树可以描述为
[[A]、[B、C]、[D、D、E、B]、#、#、#、#、#、#、D、D]
,因此我们至少有两个重复的子树作为
[[B]、[D、D]
[D]
按照代码,我们有

     A
  B      C
D   D  E   B
          D  D