Reputation: 163
You are given a binary tree in which each node contains an integer value. Find the number of paths that sum to a given value. The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
I wrote this up:
EDIT: Fixed algo, but fails on a test case.
/**
* 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);
}
}
Upvotes: 1
Views: 133
Reputation:
In the return-statement these two recursive calls are included:
pathSum(root.right, sum) + pathSum(root.left, sum)
Complete:
return pathSum(root.left, sum - root.val) + pathSum(root.right, sum - root.val) + pathSum(root.right, sum) + pathSum(root.left, sum);
This basically means that you allow the traversal to skip nodes in the middle of the path. E.g. the path 10 -> 5 -> 3 -> -2
would be part of the solution as well, since 10 + (-2) = 8
.
Now for the fix:
You need to keep track of all sums that can be found on a certain path through the tree. A way of solving this would be to keep an accumulative list of numbers:
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;
}
This solution represents a path as a list of values of nodes and finds all subsequences ending at the current node which sum up to a given value. This way no path will be covered twice.
Upvotes: 1