📜  二叉树的范围系数(1)

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

二叉树的范围系数

二叉树的范围系数(Range Sum of BST)通常是一道树相关的算法面试题。在这篇文章中,我们将介绍什么是二叉树的范围系数,以及如何使用递归和迭代两种方法来解决这个问题。

什么是二叉树的范围系数?

二叉树的范围系数定义为在给定的二叉搜索树(Binary Search Tree, BST)中,位于 L 和 R 之间的所有节点的值的总和。这里的 L 和 R 分别表示左右两个边界值。

例如,给定以下 BST:

      10
     /  \
    5   15
   / \    \
  3   7   18
  • 如果 L = 7R = 15,那么二叉树的范围系数为 32,因为只有节点 7, 1015 的值在 715 的范围内。
  • 如果 L = 3R = 13,那么二叉树的范围系数为 23,因为只有节点 3, 5, 710 的值在 313 的范围内。
解决方法
递归

递归是解决这个问题的一种直观方法。我们可以遍历二叉树,并将位于 L 和 R 之间的节点的值相加。

代码如下:

class Solution:
    def rangeSumBST(self, root: TreeNode, L: int, R: int) -> int:
        if not root:
            return 0
        if root.val > R:
            return self.rangeSumBST(root.left, L, R)
        elif root.val < L:
            return self.rangeSumBST(root.right, L, R)
        else:
            return root.val + self.rangeSumBST(root.left, L, R) + self.rangeSumBST(root.right, L, R)

首先,我们检查根节点是否为空。如果为空,返回 0,结束递归。

接下来,我们检查当前节点的值是否大于 R,如果是,那么整个右子树都不可能在范围内,我们只需要递归进入左子树,继续查找。

如果当前节点的值小于 L,那么整个左子树都不会在范围内,我们只需要递归进入右子树,继续查找。

最后,如果当前节点的值在 LR 的范围内,我们需要将当前节点的值加上左子树和右子树节点的值的总和,并返回这个总和。

总之,递归方法的时间复杂度为 O(n),其中 n 是二叉树中节点的数量。

迭代

我们还可以使用迭代方法解决这个问题。在这个方法中,我们可以使用一个栈来保存我们要遍历的节点。我们首先将根节点入栈。然后,我们在栈不为空的时候循环。在每个迭代步骤中,我们将栈顶节点出栈,并将其值加到答案中。如果该节点有左子树,则将其左子树节点入栈。如果该节点有右子树,将其右子树节点入栈。

代码如下:

class Solution:
    def rangeSumBST(self, root: TreeNode, L: int, R: int) -> int:
        if not root:
            return 0
        
        stack, ans = [root], 0
        
        while stack:
            node = stack.pop()
            if L <= node.val <= R:
                ans += node.val
            if node.left and node.val > L:
                stack.append(node.left)
            if node.right and node.val < R:
                stack.append(node.right)
        
        return ans

总体来说,迭代方法的时间复杂度与递归方法相同,都是 O(n)

至此,我们就通过递归和迭代两种方法完成了二叉树的范围系数算法题。这个问题在面试中出现的概率较高,因此对它的理解和熟练掌握将会对你的面试表现有所帮助。