具有给定总和的二叉树中的路径数

时间:2016-12-23 01:50:08

标签: java binary-search-tree

我正在解决问题https://leetcode.com/problems/path-sum-iii/ 我在这里也简要提一下: 查找二叉树中sum = sum的路径数。该路径不一定必须在根(叶)处开始(结束)。只要路径向下,就应该将其视为有效路径。

这是我的解决方案:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

public class Solution {
    public int pathSum(TreeNode root, int sum) {
        int path = 0;
        if(root.val == sum)
            return 1;
        else if(root.left == null && root.right == null)
            return 0;
        if(root.left != null){
            path += pathSum(root.left, sum - root.val);
            path += pathSum(root.left, sum);
        }
        if(root.right != null){
            path += pathSum(root.right, sum - root.val);
            path += pathSum(root.right, sum);
        }
        return path;
    }
}

根据他们的系统的答案是3,但我得到以下输入的答案为4:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1

Return 3. The paths that sum to 8 are:

1.  5 -> 3
2.  5 -> 2 -> 1
3. -3 -> 11

我花了好几个小时试图解释为什么我的代码不起作用,但我无法弄清楚问题。

抱歉一个天真的问题:(但这是杀了我!

4 个答案:

答案 0 :(得分:5)

我不确定你的解决方案有什么问题,但我认为这不对。首先,如果你的root是8,你会立即返回并只计算根作为解决方案。我就是这样做的:

GenericRepository

这个想法是在递归遍历树时沿着路径填充aarray的值,确保在返回时删除元素。当您访问节点时,您必须考虑从该节点到根路径上的任何节点的所有总和。其中任何一个都可以累加到您的参考值。当你遍历n个节点时,这个实现是O(nlogn),并且每个遍历一个len的数组遍历log(n)。

答案 1 :(得分:1)

您的代码无法满足此约束:

these nodes should be continuous.

例如此树的 root (值10)和此树的 leaf (值-2),它们的总和等于8. 它不能满足连续性,所以它无法计数。

很遗憾,您的代码无法过滤此情况。

另一种解决方案:

public class Solution {
public int pathSum(TreeNode root, int sum) {
    int path = traverse(root,sum);
    return path;
}

public int traverse(TreeNode root, int sum){
    int path = 0;
    if(root==null){
        return 0;
    }
    else{
        path += calcu(root,sum);
        path += traverse(root.left,sum);
        path += traverse(root.right,sum);
        return path;
    }
}

private int calcu(TreeNode root, int sum) {
    if(root==null){
        return 0;
    }
    else if(root.val==sum){
        return 1 + calcu(root.left,sum-root.val)+calcu(root.right,sum-root.val);
    }
    else{
        return calcu(root.left,sum-root.val)+calcu(root.right,sum-root.val);
    }
}
}

解释:traverse这个树并将每个treeNode作为根节点,在前提下找到目标路径。

答案 2 :(得分:0)

您的解决方案的问题在于它还在计算10 - 2 = 8.其中10是最顶层的根节点,-2是底部叶子。它忽略了两者之间的所有路径。

我设法用tamperedSum布尔值来解决它。

public static int pathSum(TreeNode root, int sum, boolean tamperedSum)  
{
    int path = 0;
    if(root.val == sum)
        path = 1;

    if(root.left == null && root.right == null)
        return path;

    if(root.left != null){
        path += pathSum(root.left, sum - root.val, true);
        if (!tamperedSum)
            path += pathSum(root.left, sum, false);
    }   
    if(root.right != null){
        path += pathSum(root.right, sum - root.val, true);
        if (!tamperedSum)
            path += pathSum(root.right, sum, false);
    }   
    return path;
}   

当我们从原始总和(在这种情况下是8)中扣除(节点的)值时,tamperedSum布尔值设置为true。

我们将其调用为:

pathSum(root, sum, false)

这个想法是,如果总和已被<篡改,即路径上的节点值已被扣除,我们将不再允许将其按原样传递给节点下方的分支。

因此,每当我们从总和中扣除节点值时,我们就会将tamperedSum设置为truesum - root.value。之后,不允许其下面的所有节点通过sum而不从中扣除其节点值。

答案 3 :(得分:0)

您的解决方案的问题在于,如果您处于新的内部路径,则不会从初始总和开始。

因此,当您移动内部路径时,您应该跟踪住宿金额和原始金额。

在下面找到您的算法的修改副本。

public static class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    boolean visitedAsRoot = false;

    TreeNode(int x) {
        val = x;
    }
}

public static int pathSum(TreeNode root, int accomulate, int sum) {
    int path = 0;
    if (root.val == accomulate)
        return 1;
    else if (root.left == null && root.right == null)
        return 0;
    if (root.left != null) {
        path += pathSum(root.left, accomulate - root.val, sum);
        if (!root.left.visitedAsRoot) {
            root.left.visitedAsRoot = true;
            path += pathSum(root.left, sum, sum);
        }
    }
    if (root.right != null) {
        path += pathSum(root.right, accomulate - root.val, sum);
        if (!root.right.visitedAsRoot) {
            root.right.visitedAsRoot = true;
            path += pathSum(root.right, sum, sum);
        }
    }
    return path;
}

public static void main(String args[]) {
    TreeNode t1 = new TreeNode(3);
    TreeNode t2 = new TreeNode(-2);
    TreeNode t3 = new TreeNode(1);
    TreeNode t4 = new TreeNode(3);
    TreeNode t5 = new TreeNode(2);
    TreeNode t6 = new TreeNode(11);
    TreeNode t7 = new TreeNode(5);
    TreeNode t8 = new TreeNode(-3);
    TreeNode t9 = new TreeNode(10);

    t4.left = t1;
    t4.right = t2;

    t5.right = t3;

    t7.left = t4;
    t7.right = t5;

    t8.right = t6;

    t9.left = t7;
    t9.right = t8;

    System.out.println(pathSum(t9, 8, 8));
}