【问题标题】:Summing all Nodes in BST within an inclusive range? [duplicate]在包含范围内对 BST 中的所有节点求和? [复制]
【发布时间】:2021-09-28 06:51:42
【问题描述】:

所以我需要总结一个包含范围内的 BST 中的所有节点。例如,如果范围为 [7, 15]('[' 和 ']' 均指包括在内),

    10
   /  \
  5    15
 / \     \
3   7    18

总和是 7 + 10 + 15 = 32

下面是我的代码,我正在做一个简单的 inOrderTraversal,但由于某种原因,结果总和为 0。

class Solution {
    public int rangeSumBST(TreeNode root, int low, int high) {
        int sum = 0;
        helper(root, low, high, sum);
        return sum;
    }
    
    public void helper(TreeNode root, int low, int high, int sum) {
        
        if(root != null) {
            helper(root.left, low, high, sum);
            if(root.val >= low && root.val <= high) {
                System.out.println("sum before was " + sum);
                sum = sum + root.val;
                System.out.println("sum after was " + sum);
            }
            helper(root.right, low, high, sum);
        }
    }
}

有人知道为什么是0吗?

【问题讨论】:

  • 因为int在java中不是引用类型,所以每一帧(方法)都有自己的sum变量的副本

标签: java binary-search-tree inorder


【解决方案1】:

原因是helper的每个函数执行上下文都有自己的sum变量。因此,对该变量的任何赋值只会影响 那个 变量,而不是恰好具有相同名称的调用者的变量。

按值传递

有些语言有传递变量的引用的概念,所以这样的整数确实会被调用者和被调用者共享,但在Java中参数是传递的按价值。

返回值

在这种情况下,一个解决方案是使递归函数return成为一个总和:仅与以该节点为根的子树中的节点相关的总和。调用者可以将返回的总和添加到自己的总和中。

这意味着您不再需要额外的 sum 参数:sum 可以只是一个以 0 开头的局部变量,将更深层次调用的结果添加到该变量中,并最终返回给调用者。

这意味着helper 函数实际上与rangeSumBST 具有相同的签名,因此我们可以将rangeSumBST 本身用作递归函数。

优化

可以优化您的幼稚中序遍历,仅在子树有可能在范围内的节点时访问子节​​点。如果没有,那就不要访问它。

下面是考虑到这些点的函数版本:

class Solution {
    public int rangeSumBST(TreeNode root, int low, int high) {
        if (root == null) return 0;
        int val = 0;
        if (root.val >= low && root.val <= high) val += root.val;
        if (root.val < high) val += rangeSumBST(root.right, low, high);
        if (root.val >  low) val += rangeSumBST(root.left,  low, high);
        return val;
    }
}

【讨论】:

  • 将参数命名为 root 具有误导性,因为大多数时候它是使用非根节点调用的。
  • @Andreas,每个节点都是它自己的子树的根。它实际上是一个好名字,因为它计算的总和与它作为根的那棵树有关。
  • 如果每个节点都是根,为什么类不命名为TreeRoot。对不起,我不认同你的论点。但是,这是你的答案,所以你可以随意命名。
猜你喜欢
  • 2021-10-03
  • 2012-10-07
  • 1970-01-01
  • 1970-01-01
  • 2022-09-29
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多