查找范围中包含的bst的最大子树的大小

时间:2016-11-07 01:40:52

标签: algorithm binary-search-tree

这是最近一次采访问题。要求查找NA范围内包含的最大BST子树大小的问题为[x, y]。 BST是递归定义的,其中每个节点具有整数值,左子节点和右子节点。我只能在树中的节点总数位于该范围内但无法找到最大的子树。这是我在python中使用的代码:

x < y

解决方案应该是def solution(x, y, T): if T is None: return 0 size = 0 if x < T.val: size += solution(x, y, T.left) if x <= T.val and y >= T.val: size += 1 # The following if statement was my attempt at resetting the count # whenever we find a node outside the range, but it doesn't work if x > T.val or y < T.val: size = 0 if B > T.x: size += solution(A, B, T.right) return size ,其中O(N)是树中节点的数量。

3 个答案:

答案 0 :(得分:1)

我们可以递归地解决问题。我们需要知道每个子树的左边界和右边界(即最小和最大的元素)。如果它位于[x,y]范围内,我们可以用当前子树的总大小更新答案。这是一些代码(solution函数返回一个元组,在答案之上有一些额外的信息。如果只是想让它返回范围内最大子树的大小,你可以将它包装起来并用作一个辅助功能)。

def min_with_none(a, b):
    """
    Returns the minimum of two elements.   
    If one them is None, the other is returned.
    """
    if a is None:
        return b
    if b is None
        return a
    return min(a, b)


def max_with_none(a, b):
    """
    Returns the maximum of two elements.   
    If one them is None, the other is returned.
    """
    if a is None:
        return b
    if b is None:
        return a
    return max(a, b)


def solution(x, y, T):
    """
    This function returns a tuple 
    (max size of subtree in [x, y] range, total size of the subtree, min of subtree, max of subtree) 
    """
    if T is None:
        return (0, 0, None, None)

    # Solves the problem for the children recursively
    left_ans, left_size, left_min, _ = solution(x, y, T.left)
    right_ans, right_size, _, right_max = solution(x, y, T.right)

    # The size of this subtree
    cur_size = 1 + left_size + right_size

    # The left border of the subtree is T.val or the smallest element in the
    # left subtree (if it's not empty)
    cur_min = min_with_none(T.val, left_min)

    # The right border of the subtree is T.val or the largest element in the 
    # right subtree (if it's not empty)
    cur_max = max_with_none(T.val, right_max)

    # The answer is the maximum of answer for the left and for the right 
    # subtree
    cur_ans = max(left_ans, right_ans)
    # If the current subtree is within the [x, y] range, it becomes the new answer,
    # as any subtree of this subtree is smaller than itself
    if x <= cur_min and cur_max <= y:
        cur_ans = cur_size 

    return (cur_size, cur_ans, cur_min, cur_max)

此解决方案显然以线性时间运行,因为它只访问每个节点一次,并且每个节点执行一定数量的操作。

答案 1 :(得分:0)

对于BST中的每个节点,您可以为其指定有效范围 [Li,Ri] ,这意味着该节点的子树中的所有元素都位于有效范围内。

您可以轻松地递归定义这些范围:

对于节点 i ,我们假设范围为 [Li, Ri] ,此节点中存储的值为 val 的。 对于 i 的左孩子,范围是 [Li, val − 1] 。同样对于正确的孩子,范围是 [val + 1, Ri]

对于根节点,有效范围是 [−inf, inf]

答案 2 :(得分:0)

假设我们的size函数返回-1表示无效的子树。如果节点的值和其子树中的所有值都在范围内,则(子)树有效。

# returns a tuple: (size of T, best valid size among itself and its subtrees)
def f(x,y,T): 
  if T is None: 
    return (0,0)

  l_size, l_best = f(x,y,T.left) 
  r_size, r_best = f(x,y,T.right) 

  if x <= T.value <= y and l_size >= 0 and r_size >= 0:
    return (1 + l_size + r_size,1 + l_size + r_size)
  else:
    return (-1,max(l_best,r_best))