LeetCode 938:二叉搜索树的范围和 — 详解递归与JavaScript实现
2023-11-29 08:36:28
在二叉搜索树中使用递归寻找指定范围的节点并求和
在计算机科学中,二叉搜索树(BST)是一种特殊的数据结构,它利用二叉树的特性来高效地存储和检索数据。在 BST 中,每个节点的值都比其左子树中的所有值大,并且比其右子树中的所有值小。
在本文中,我们将探讨如何使用递归算法在二叉搜索树中查找指定范围的节点并计算它们的总和。该算法将使用深度优先搜索(DFS)策略,以系统且高效的方式遍历 BST。
理解问题
给定一棵二叉搜索树和一个范围 [low, high]
,我们的目标是找到树中所有满足 low <= node.val <= high
条件的节点,并计算它们的总和。
例如,考虑以下二叉搜索树:
10
/ \
5 15
/ \ / \
3 7 13 18
/ \ / \
1 6 8 null
如果我们给定的范围是 [6, 10]
,那么满足条件的节点是:
- 6
- 7
- 8
- 10
因此,总和为 6 + 7 + 8 + 10 = 31 。
递归算法
为了解决这个问题,我们将使用递归算法,该算法按照以下步骤工作:
- 递归基线: 如果当前节点为
null
,则返回 0,因为没有节点可以求和。 - 检查范围: 如果当前节点的值在给定的范围内(
low <= node.val <= high
),则将当前节点的值添加到总和中。 - 递归左子树: 递归调用算法,传递左子树作为参数。
- 递归右子树: 递归调用算法,传递右子树作为参数。
- 返回总和: 返回当前节点的值(如果在范围内)和左子树和右子树总和的总和。
JavaScript 实现
以下是使用 JavaScript 实现的递归算法:
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* Given a binary search tree and a range [low, high], return the sum of the values of all the nodes in the BST that are in the given range.
*
* @param {TreeNode} root The root node of the binary search tree.
* @param {number} low The lower bound of the range.
* @param {number} high The upper bound of the range.
* @return {number} The sum of the values of the nodes in the range.
*/
const rangeSumBST = (root, low, high) => {
// Base case: if the current node is null, return 0.
if (!root) {
return 0;
}
// Check if the current node's value is in the given range.
let sum = 0;
if (root.val >= low && root.val <= high) {
// If the current node's value is in the range, add it to the sum.
sum += root.val;
}
// Recursively calculate the sum for the left and right subtrees.
sum += rangeSumBST(root.left, low, high);
sum += rangeSumBST(root.right, low, high);
// Return the sum of the current node's value and the sum of the left and right subtrees.
return sum;
};
复杂度分析
- 时间复杂度: O(n),其中 n 是二叉搜索树中的节点数。这是因为递归算法需要遍历树中的每个节点。
- 空间复杂度: O(n),这是因为递归调用需要额外的空间来存储函数调用堆栈。
总结
使用递归算法,我们可以有效地查找二叉搜索树中指定范围内的节点并计算它们的总和。该算法利用 BST 的特性,使用深度优先搜索策略系统地遍历树。我们提供了 JavaScript 实现,并分析了算法的复杂度。
常见问题解答
-
为什么使用递归算法?
递归算法适合此问题,因为它允许我们通过在每个子树上重复相同的过程来分解问题。 -
如何处理空树?
在递归基线情况下,如果当前节点为null
,我们将返回 0。 -
如果给定的范围无效(例如
low > high
),该怎么办?
在这种情况下,算法将返回 0,因为没有节点满足指定的范围。 -
算法是否可以扩展到多维范围(例如,查找指定矩形范围内的节点)?
该算法可以扩展到多维范围,但需要进行一些修改以适应不同的维度。 -
是否有其他方法可以解决这个问题?
除了递归算法,还有其他方法可以解决这个问题,例如使用迭代法或二分搜索。