【问题标题】:Sum of nodes between two BST leaves两个 BST 叶之间的节点总和
【发布时间】:2020-01-16 06:59:55
【问题描述】:

我不是在寻找树的最大和路径。我可以创建并找到二叉搜索树的总和,但我需要找到两个叶子之间所有节点的总和。

例如,对于使用这些节点构建的 BST:5、10、13、8、3、4、5,树如下所示:

                         5
                     /       \
                   3           10
                    \         /  \
                     4       8    13
                            /
                           5

所以如果输入是4和13,那么节点的和就是3+5+10=18。

函数可能是这样的:Sum(tree, firstNumber, secondNumber);

我正在考虑创建所有节点的两个有序列表,直到根节点并查看它们中的任何一个是否是公共的,然后将所有唯一节点的值相加。这在时间复杂度和内存管理方面很糟糕,所以我想看看是否有更简单的方法

编辑:M. Hazara 是对的,5 不是一片叶子。所以我删除了那个例子

【问题讨论】:

  • 我认为叶子意味着没有孩子的节点...... ????你确定你可以将根定义为叶子???
  • 两个步骤:1. 找到最低的共同祖先,2. 使用常规 BST 搜索两者并将遇到的所有节点相加
  • @M.Hazara 你是对的,我更新了示例。
  • @Primusa,所以对每个或同时进行 BST 搜索?
  • 每个节点的 BST,并将您看到的每个节点相加。你可能最终会添加两次 LCA,所以最后减去它

标签: c# algorithm tree binary-search-tree


【解决方案1】:

嗯,可能想到的第一个想法是为两个叶子经过的每个节点制作一个列表。但是,由于它是二叉搜索树 (BST),因此采用哪条路径的条件是已知的,因此可以跟踪哪些节点在公共路径中,哪些不在。

首先,BST 搜索总是从根节点开始,所以它总是和的一部分,假设 BST 有 3 个或更多节点,因为我们需要两个叶子。其次,必须对每个叶子 (firstNumber,secondNumber) 进行 BST 搜索,以确保我们遍历了每条路径的节点,无论它们是否常见。最后,剩下的就是确定一个节点何时在两条路径中是公共的,因此我们不会将相同的值添加两次。

如果两个 BST 搜索采用相同的路径,则节点位于公共路径中。因此,您必须在函数内同时运行两者。我们可以使用 do-while 来计算 sum 中的所有公共节点:

firstCurrentNode = tree.Root;
secondCurrentNode = tree.Root;
do {
  sum += firstCurrentNode;
  // FirstNumber path check:
  if (firstNumber < firstCurrentNode) firstCurrentNode = firstCurrentNode.goLeftNode();
  else firstCurrentNode = firstCurrentNode.goRightNode();
  // SecondNumber path check:
  if (secondNumber < secondCurrentNod) secondCurrentNode = secondCurrentNode.goLeftNode(); 
  else secondCurrentNode = secondCurrentNode.goRightNode(); 
} while (firstCurrentNode == secondCurrentNode)

一旦它们不相等,即采用不同的路径,由于树的属性,它们将永远不会再共享相同的路径。因此,我们只需要单独继续 BST 搜索,包括我们找到的每个节点。但是,我们可能已经到达叶子了,所以有必要先检查一下:

// Search for firstNumber
while(firstCurrentNode != firstNumber) {
  sum += firstCurrentNode;
  if (firstNumber < firstCurrentNode) firstCurrentNode = firstCurrentNode.goLeftNode();
  else firstCurrentNode = firstCurrentNode.goRightNode();
}
// Search for secondNumber
while(secondCurrentNode != secondNumber) {
  sum += secondCurrentNode;
  if (secondNumber < secondCurrentNod) secondCurrentNode = secondCurrentNode.goLeftNode(); 
  else secondCurrentNode = secondCurrentNode.goRightNode();
}

当然,我假设使用的叶子存在于树中,并且所有节点都包含唯一值,您可以对此进行调整,但这是一种无需使用更多内存空间或获得更差性能即可获得总和的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    相关资源
    最近更新 更多