📜  门| GATE CS 2019 |问题 7(1)

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

门 | GATE CS 2019 |问题 7

这个问题属于计算机科学领域,是计算机科学系列考试的一部分,常见于印度。它考察了一个二叉树的各种遍历方式以及二叉树的性质。

题目描述

给定一棵二叉树,节点编号从1到N,N是奇数。每个节点有一个关键字和颜色。一棵树是“平衡的”,如果所有的叶子节点具有相同的深度,并且最底层的叶子节点是黑色的。

现在,你需要确定这棵树是平衡的还是非平衡的,如果是非平衡的,就输出深度最浅的黑色叶子节点的深度。

输入

第一行包含一个整数T,表示测试用例的数量。对于每个测试用例,第一行包含一个整数N,表示二叉树中节点的数量。接下来的N行描述了节点i(1 <= i <= N)。每一行包括一个整数Ci,表示节点的颜色,和一个整数Ki,表示节点的关键字,描述前两个节点的父节点和左/右儿子的编号(如果存在的话)。如果儿子不存在,那么它的编号是0。

输出

对于每个测试用例,如果树是平衡的,就输出“YES”。如果树不平衡,则输出深度最浅的黑色叶子节点的深度。

示例
输入:
2
3
1 20 0 2
2 10 1 0
3 30 1 0
3
1 20 0 2
-1 10 1 0
-1 30 1 0
输出:
YES
2
解释

在第一种情况下,树是平衡的,因此输出YES。在第二种情况下,树的最短黑色叶子节点的深度为2,因此输出2。

思路

首先,我们需要遍历二叉树,以保证我们拥有所有节点的信息。然后,我们可以使用任何一种遍历方法,但是最好的选择是后序遍历。为什么?因为我们需要先处理子问题,然后才能处理父问题。

我们首先检查当前节点是否为黑色叶子节点,如果是,则记录其深度。否则,如果该节点是黑色,我们将其深度添加到左子树和右子树的深度中,然后比较左子树和右子树的深度,并将较小的深度添加到当前节点的深度中。最后,我们返回该节点的深度。

如果该节点是红色,则我们只考虑其子树的深度,并返回其子树中较小的深度。

最后,我们检查最顶层的节点是否为黑色,并输出“YES”或最小黑色叶子节点的深度。

代码实现
def is_balanced_tree(root):
    """
    :type root: Node
    :rtype: Tuple[bool, int]
    """
    if root is None:
        return True, 0
    lb, ld = is_balanced_tree(root.left)
    rb, rd = is_balanced_tree(root.right)
    depth = max(ld, rd) + 1
    if lb and rb and ld == rd:
        if root.color == "black":
            return True, depth
        else:
            return False, depth
    else:
        return False, depth