给定二叉树,计算其中存在的二叉搜索树的数量

时间:2016-03-18 14:13:08

标签: algorithm data-structures tree binary-tree binary-search-tree

给出了二叉树,我们必须计算其中的二叉搜索树的数量。每个叶节点都是BST
我使用了以下方法。
对于bt中的每个节点,检查它是否为bst 上述方法的时间复杂度为O(n 2 )。我们如何以有效的方式O(n)来实现。

2 个答案:

答案 0 :(得分:1)

树的简单递归遍历返回一些额外的数据可能有助于在 O(n)时间内管理它,n是节点数。您可以在下面找到Python中的实现。

numBST = 0
def traverse(root):
    global numBST
    leftComplies = True
    rightComplies = True
    rootRange = [root.val, root.val]
    if root.left != None:
        leftResult = traverse(root.left)
        leftComplies = leftResult[0] and leftResult[1][1] < root.val
        rootRange[0] = leftResult[1][0]
    if root.right != None:
        rightResult = traverse(root.right)
        rightComplies = rightResult[0] and rightResult[1][0] > root.val
        rootRange[1] = rightResult[1][1]
    if leftComplies and rightComplies:
        numBST += 1
    return (leftComplies and rightComplies, rootRange)

使用二叉树的根作为参数运行遍历后,numBST将包含根目录中的BST数。

上面给出的函数遍历以递归的方式遍历其树根作为参数。对于每个节点V,如果V具有左子L,则它递归地遍历左子节点并返回一些数据。具体来说,它返回一个长度为2的列表。列表中的第一个元素是一个布尔值,表示以L为根的左子树是否为BST。返回列表的第二个元素包含另一个列表,该列表分别包含以L为根的子树中的最小值和最大值。

对于以V为根的树为BST,以L为根的子树也必须是BST AND 根据L的子树中的最大值(因此该子树中的所有值)必须小于存储在V中的值。因此,在递归调用L的遍历后,我们检查返回的数据以确定是否满足这些条件。

类似地,如果存在V的右子R,则递归遍历。要成为BST,以V为根的树也必须满足以R为根的树是BST AND 以R为根的子树的最小节点(因此该子树中的所有节点)包含的条件一个大于V。

中存储的值的值

如果满足所有这些条件,则可以将以V为基础的树视为BST,并相应地更新存储在numBST中的结果。请注意,我们还会更新存储在V中的最小值和最大值,因为我们递归遍历其子L和R,并执行上面提到的检查,以便我们将正确更新的值传递给更高级别的递归。

答案 1 :(得分:1)

如果我正确理解了这个问题,可以解决如下问题;一个将旨在计算作为二进制搜索树的根的节点的数量。正如已经提到的,每个叶子都是二元搜索树的根。非叶节点a是二进制搜索的根,当且仅当a的左子节点是二叉搜索树时,b的右子节点是二元搜索树和a左子项下所有值的最大值不大于a的值,并且a右子项下所有值的最小值更大或等于a的值。可以通过递归评估来完成对此属性的评估,该评估仅对每个节点进行一次访问,从而产生线性运行时限。