使用DFS的BST范围总和

问题描述

问题::给定二叉搜索树的根节点,返回值介于L和R之间(包括L和R)的所有节点的值之和。

保证二进制搜索树具有唯一值。

示例1:

输入:root = [10,5,15,3,7,null,18],L = 7,R = 15

输出:32

密码问题:https://leetcode.com/problems/range-sum-of-bst/

我的方法:我正在尝试执行dfs并访问每个节点,如果该节点上的值适合约束,那么我想在递归函数中返回它。然后,我将所有值加起来并将其返回给我的主函数

我仍在尝试理解递归,我在这代码中做错了什么(为什么它只返回10而不返回32?)。

我试图从每个递归函数中返回一个值并将其添加到最后-这样做有意义吗?

/**
 * DeFinition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val,TreeNode left,TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int rangeSumBST(TreeNode root,int L,int R) {
        if(root == null) {
            return 0;
        }

        rangeBST(root,L,R);
        
        return rangeBST(root,R);
    }
    
    public static int rangeBST(TreeNode root,int R) {
        if(root == null) {
            return 0;
        }
        
        if(root.val >= L && root.val <= R) {
            return root.val;
        }

        int x = rangeBST(root.left,R);
        int y = rangeBST(root.right,R);
        
        return x + y;
    }
}

解决方法

您在末尾添加这些值并使用返回值的方法是正确的。 (在使用指针算术或通过引用变量传递的语言中,可以将引用传递给整数,并增加返回值,而无需返回值。) 但是与“ return root.val”一致,您就有问题了。

public int rangeSumBST(TreeNode root,int l,int r) {
        if(root == null)
            return 0;

        // This is a problem because you are stopping with your recursive search
        // if one value was found. This is the reason because it is returning 10 in your example
        // if(root.val >= L && root.val <= R) return root.val;

        int result = 0;
        // So your looking at your node,if the value is in the range you want.
        if (root.val >= l && root.val <= r)
            result += root.val;

        // Add the ranged summ of your left node
        result += rangeSumBST(root.left,l,r);
        // Add the ranged summ of your right node
        result += rangeSumBST(root.right,r);

        // And your done
        return result;
    }
,

两个问题:

  • 当该值在L-R范围之间时,该算法应更深地重现,但您将返回当前节点自身的值,而不会更深。

  • 该算法不必总是需要访问每个节点,而是要利用BST属性:仅当当前值不排除查找任何子树时,才应在左侧子树中搜索子树中的范围内的值。

    例如,如果当前节点的值为3,并且LR范围为(5,9),则在左侧子树中进一步查找是没有意义的,因为所有 值都为无论子树有多大,都保证小于3。

    对于右子树可能也有类似的观察结果。

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