为什么这个算法不适用于树中的路径和?

时间:2017-04-04 17:53:15

标签: java

  

您将获得一个二叉树,其中每个节点都包含一个整数值。   找到与给定值相加的路径数。   路径不需要在根或叶子上开始或结束,但必须向下(仅从父节点到子节点)。

我写了这个:

编辑:修复算法,但在测试用例中失败。

 /**
 * 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) {
        if(root == null) return 0;
        return helper(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
    }

    public int helper(TreeNode node, int sum){
        if(node == null) return 0;
        if(node.val == sum) return 1;
        return helper(node.left, sum - node.val) + helper(node.right, sum - node.val);
    }

}

1 个答案:

答案 0 :(得分:1)

在return语句中包含了这两个递归调用:

pathSum(root.right, sum) + pathSum(root.left, sum)

达成:

return pathSum(root.left, sum - root.val) + pathSum(root.right, sum - root.val) + pathSum(root.right, sum) + pathSum(root.left, sum);

这基本上意味着您允许遍历跳过路径中间的节点。例如。路径10 -> 5 -> 3 -> -2也是解决方案的一部分,因为10 + (-2) = 8

现在进行修复:
您需要跟踪可以在树中的特定路径上找到的所有总和。解决这个问题的一种方法是保留一个累积的数字列表:

public int pathSum(TreeNode n, Stack<Integer> acc, int sum){
    if(n == null){
        return 0;
    }

    int count = 0;
    int totalToNode = acc.peek() + n.val;

    //increment count, if the nodes value matches (path of length 1)
    if(n.val == sum)
        count++;

    //increment count, if the path from root to n sums up to the given value
    if(totalToNode == num)
        count++;

    //find all paths that end in n and sum up to the searched sum
    for(int s : acc)
        if(totalToNode - s == sum)
            count++;

    acc.push(totalToNode);

    //number of matching paths for left and right subtree
    count += pathSum(n.left, acc, sum);
    count += pathSum(n.right, acc, sum);

    acc.pop();

    return count;
}

此解决方案将路径表示为节点值列表,并查找在当前节点处结束到达给定值的所有子序列。这样就不会有两次覆盖路径。