【问题标题】:use post-order binary tree traverse to calculate number of subtrees使用后序二叉树遍历计算子树数
【发布时间】:2021-03-24 22:34:33
【问题描述】:

我正在练习一些 Leetcode 树/递归问题。我仍然没有掌握他们的窍门。问题是给定二叉树的根,返回子树的数量,其中所有节点具有相同的值。 https://leetcode.com/explore/learn/card/data-structure-tree/17/solve-problems-recursively/538/.我的解决方案返回的子树比正确答案少。我想不通。谢谢。

class Solution:
    def countUnivalSubtrees(self, root: TreeNode) -> int:
        if root is None:
            return 0
        
        self.count = 0
        self.isUnivalSubtree(root)
        return self.count
    
    def isUnivalSubtree(self, root:TreeNode) -> bool:
        
        if (root.left is None) and (root.right is None):
            self.count += 1
            return True

        if (root.left is None) and (root.right is not None):
            if self.isUnivalSubtree(root.right) and (root.val == root.right.val):
                self.count += 1
                return True
            else:
                return False
            
        if (root.right is None) and (root.left is not None):
            if self.isUnivalSubtree(root.left) and (root.val == root.left.val):
                self.count += 1
                return True
            else:
                return False
            
        if (root.right is not None) and (root.left is not None):
            if self.isUnivalSubtree(root.left) and self.isUnivalSubtree(root.right) and (root.val == root.left.val) and (root.val == root.right.val):
                self.count += 1
                return True
            else:
                return False

【问题讨论】:

  • 这个问题被付费墙阻止了。如果您可以分享一些输入和预期输出,那就太好了。

标签: python recursion


【解决方案1】:

递归

我们可以使用inductive reasoning来无痛解决问题-

  1. 如果输入树t 为空,则没有可计数的数据。返回空计数,0
  2. (感应)t 不为空。如果t 是单值,则返回1 加上递归子问题的结果t.leftt.right
  3. (归纳)t 不是空的,也不是单值。返回递归子问题的结果之和,t.leftt.right
def count_univals(t):
  if not t:
    return 0                                                   #1
  elif is_unival(t):
    return 1 + count_univals(t.left) + count_univals(t.right)  #2
  else:
    return count_univals(t.left) + count_univals(t.right)      #3

这取决于定义is_unival,我们可以使用类似的推理来做到这一点 -

  1. 如果输入树t 为空,则没有可比较的内容。返回真
  2. (感应)t 不为空。如果t.val 与比较值q 匹配,则返回true,并且递归子问题(t.left, q)(t.right, q) 也是单变量。否则返回 false。
def is_unival(t, q):
  if not t:
    return True                                                          #1
  else:
    return t.val == q and is_unival(t.left, q) and is_unival(t.right, q) #2

迭代

也许你用通用的遍历方法写更直观,比如preorder-

def count_unival_subtrees(t):
  return sum(1 if is_unival(node) else 0 for node in preorder(t))

def is_unival(t):
  for node in preorder(t):
    if node.val != t.val:
      return False
  return True

def preorder(t):
  if not t: return
  yield t
  yield from preorder(t.left)
  yield from preorder(t.right)

演示

无论您选择哪种实现方式,它们的工作方式都相同 -

t1 = node(1, node(1, node(2), node(1)), node(1, None, node(2)))
#     1
#    / \
#   1   1
#  / \   \
# 2   1   2

print(count_univals(t1))
3

这是一个稍微复杂一点的树 -

t2 = node \
  ( 1
  , node(2, node(2, node(2), node(2)), node(5))
  , node(3, None, node(3, node(3), node(3)))
  )
#       1
#      / \
#     2   3
#    / \   \
#   2   5   3
#  / \     / \
# 2   2   3   3 
print(count_univals(t2))
8

【讨论】:

  • 这是一个非常好的答案。谢谢!欣赏!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
  • 2020-01-15
  • 1970-01-01
  • 2012-01-01
  • 2022-11-11
  • 1970-01-01
相关资源
最近更新 更多