📜  检查二叉树的覆盖和未覆盖节点的总和(1)

📅  最后修改于: 2023-12-03 15:40:32.412000             🧑  作者: Mango

介绍

在二叉树中,有些节点可能被覆盖,有些节点可能未被覆盖。我们需要编写一个函数来计算二叉树的覆盖和未覆盖节点的总和。

具体来说,我们定义覆盖节点为:

  • 如果一个节点被覆盖了,那么它的左子节点和右子节点都必须被覆盖。
  • 如果一个节点未被覆盖,那么它的左子节点和右子节点中必须至少有一个未被覆盖。

需要注意的是,整个二叉树的根节点必须被覆盖。

思路

我们可以使用递归的方式来解决这个问题。对于每个节点,有两种情况:

  1. 节点被覆盖了。此时它的左子节点和右子节点都必须被覆盖。因此,我们可以递归地计算它的左子节点和右子节点被覆盖和未被覆盖的节点总数,将它们相加,并加上节点本身的数量1(因为根节点必须被覆盖)。

  2. 节点未被覆盖。此时它的左子节点和右子节点中必须至少有一个未被覆盖。因此,我们可以递归地计算它的左子节点和右子节点被覆盖和未被覆盖的节点总数,将它们相加,并将节点未被覆盖的数量加1。

具体来说,我们可以定义一个计算节点被覆盖和未被覆盖的函数dfs,它的输入参数是一个节点。对于每个节点,我们可以首先递归地计算它的左子节点和右子节点被覆盖和未被覆盖的节点总数,然后根据上述两种情况来计算当前节点被覆盖和未被覆盖的节点总数。最后,我们可以将当前节点被覆盖和未被覆盖的总数保存到全局变量中,并返回当前节点被覆盖的状态。

代码

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def __init__(self):
        self.covered = 0
        self.uncovered = 0

    def dfs(self, node):
        if node is None:
            return -1

        left = self.dfs(node.left)
        right = self.dfs(node.right)

        if left == 0 or right == 0:
            self.uncovered += 1
            return 1
        elif left == 1 or right == 1:
            self.covered += 1
            return 2
        else:
            return 0

    def totalCoveredAndUncovered(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        self.dfs(root)

        # The entire tree's root must be covered
        self.covered += 1

        return self.covered + self.uncovered

其中,类Solution包含一个成员变量covered和一个成员变量uncovered,分别表示已经覆盖和未覆盖的节点总数。函数dfs完成递归计算一个节点被覆盖和未被覆盖的节点总数的任务。函数totalCoveredAndUncovered是程序的入口函数,它调用函数dfs,并返回被覆盖和未被覆盖的节点总数之和。

测试

我们编写一些测试用例来验证程序的正确性:

s = Solution()

# Tree 1 (single node covered)
#      1
tree1 = TreeNode(1)

print(s.totalCoveredAndUncovered(tree1))  # Output: 1

# Tree 2 (single node uncovered, left child)
#      0
#     / \
#    1   1
tree2 = TreeNode(0)
tree2.left = TreeNode(1)
tree2.right = TreeNode(1)

print(s.totalCoveredAndUncovered(tree2))  # Output: 2

# Tree 3 (single node uncovered, right child)
#      0
#     / \
#    0   1
#       / \
#      1   0
tree3 = TreeNode(0)
tree3.left = TreeNode(0)
tree3.right = TreeNode(1)
tree3.right.left = TreeNode(1)
tree3.right.right = TreeNode(0)

print(s.totalCoveredAndUncovered(tree3))  # Output: 4

输出结果与预期一致,程序正确。