Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用DFS的BST范围和_Java_Recursion_Tree_Binary Tree_Depth First Search - Fatal编程技术网

Java 使用DFS的BST范围和

Java 使用DFS的BST范围和,java,recursion,tree,binary-tree,depth-first-search,Java,Recursion,Tree,Binary Tree,Depth First Search,问题:给定二叉搜索树的根节点,返回值介于L和R(包括L和R)之间的所有节点的值之和 二叉搜索树保证具有唯一的值 例1: 输入:root=[10,5,15,3,7,null,18],L=7,R=15 产出:32 Leetcode问题: 我的方法:我正在尝试执行dfs并访问每个节点,如果该节点上的值符合约束条件,那么我希望在递归函数中返回它。然后,我将所有值相加,并将其返回到我的主函数 我仍在试图理解递归,我在这段代码中做错了什么(为什么它只返回10而不是32?) 我试图从每个递归函数返回一个值,并

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

二叉搜索树保证具有唯一的值

例1:

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

产出:32

Leetcode问题:

我的方法:我正在尝试执行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, L, R);
    }
    
    public static int rangeBST(TreeNode root, int L, int R) {
        if(root == null) {
            return 0;
        }
        
        if(root.val >= L && root.val <= R) {
            return root.val;
        }

        int x = rangeBST(root.left, L, R);
        int y = rangeBST(root.right, L, R);
        
        return x + y;
    }
}
/**
*二叉树节点的定义。
*公共级树节点{
*int-val;
*左树突;
*特雷诺德右翼;
*TreeNode(){}
*树节点(int-val){this.val=val;}
*TreeNode(内部值,TreeNode左,TreeNode右){
*this.val=val;
*this.left=左;
*这个。右=右;
*     }
* }
*/
类解决方案{
公共内部范围(树根、内部L、内部R){
if(root==null){
返回0;
}
rangeBST(根,L,R);
返回范围BST(根、L、R);
}
公共静态整数范围BST(树节点根、整数L、整数R){
if(root==null){
返回0;
}

如果(root.val>=L&&root.val您在末尾添加这些值并使用返回值的方法是正确的。(在使用指针算术或通过引用变量传递的语言中,您可以传递对整数的引用并增加接收值,而不必返回值。) 但在使用“returnroot.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, l, r);

        // And your done
        return result;
    }
public int rangeSumBST(树节点根,int l,int r){
if(root==null)
返回0;
//这是一个问题,因为您正在停止递归搜索
//如果找到一个值,这就是原因,因为在您的示例中它返回10
//如果(root.val>=L&&root.val=L&&root.val两个问题:

  • 当值在L-R范围之间时,该算法应更深入地重现,但返回当前节点自己的值时,不会再深入查看

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

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

    右子树也有类似的观察结果

类解决方案{
公共内部范围(树根、内部L、内部R){
if(root==null)返回0;
int-val=0;
如果(root.val>=L&&root.val L)val+=rangeSumBST(root.left,L,R);
返回val;
}
}

我完全同意您的第一个问题,但我认为第二个问题不是真正的问题,因为您的运行时复杂性仍然是O(N)(它没有改变)但是你必须进一步增加圈复杂度,以改善二进制树的随机情况下的中间运行时间。如果证明这个函数是一个瓶颈,这是唯一应该做的。我不认为时间复杂度改变了,但是我认为这仍然是个问题,因为最佳情况的时间复杂度从O(n)提高到O(1)。,这会对站点上的运行时间产生相当大的影响,在这些站点上,运行时间会被测量并得到比较分数(如:Leetcode)运行到TLE的解决方案。因此,不仅时间复杂度很重要,绝对运行时间也很重要。是的,它会对绝对运行时间产生重大影响。但是,如果不是绝对有必要优化运行时间,我不会添加进一步的逻辑,因为可能存在更多的变异、错误源和可维护性问题。这是你的自由选择。我更喜欢利用给定的信息,这涉及到一个BST,而不仅仅是一个二叉树。附加的
if
条件是BST的典型条件,因此预计在所有涉及BST导航的代码中都会有这样的逻辑。
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, L, R);
        return val;
    }
}