Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
For example:
Given the below binary tree and sum = 22,
5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.
Java Solution 1 – Using Queue
Add all node to a queue and store sum value of each node to another queue. When it is a leaf node, check the stored sum value.
For the tree above, the queue would be: 5 – 4 – 8 – 11 – 13 – 4 – 7 – 2 – 1. It will check node 13, 7, 2 and 1. This is a typical breadth first search(BFS) problem.
/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public boolean hasPathSum(TreeNode root, int sum) { if(root == null) return false; LinkedList<TreeNode> nodes = new LinkedList<TreeNode>(); LinkedList<Integer> values = new LinkedList<Integer>(); nodes.add(root); values.add(root.val); while(!nodes.isEmpty()){ TreeNode curr = nodes.poll(); int sumValue = values.poll(); if(curr.left == null && curr.right == null && sumValue==sum){ return true; } if(curr.left != null){ nodes.add(curr.left); values.add(sumValue+curr.left.val); } if(curr.right != null){ nodes.add(curr.right); values.add(sumValue+curr.right.val); } } return false; } } |
Java Solution 2 – Recursion
public boolean hasPathSum(TreeNode root, int sum) { if (root == null) return false; if (root.val == sum && (root.left == null && root.right == null)) return true; return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val); } |
Thanks to nebulaliang, this solution is wonderful!
–
A null root and sum==0 should return true, right? 😉
Also, numbers can be negative, so I didn’t add any optimization.
boolean hasPathSum(Node n, int sum)
{
if (n == null) return sum == 0;
return
hasPathSum(n.left, sum - n.val))
||
hasPathSum(n.right, sum - n.val);
}
C# implementation:
public static bool IsPathExists(TreeNode root, int sum, out List numbers)
{
if (root == null)
{
numbers = null;
return false;
}
else
{
List tempList = new List();
var op = IsPathExistRecurse(root, sum, ref tempList);
numbers = tempList;
return op;
}
}
private static bool IsPathExistRecurse(TreeNode root, int sum, ref List numbers)
{
if (root == null)
{
return false;
}
else
{
numbers.Add(root.Data);
if (root.Data == sum && (root.Left == null && root.Right == null))
return true;
else
{
if (IsPathExistRecurse(root.Left, sum – root.Data, ref numbers))
{
return true;
}
else if (null != root.Left && numbers.Contains(root.Left.Data))
{
numbers.Remove(root.Left.Data);
}
if (IsPathExistRecurse(root.Right, sum – root.Data, ref numbers))
{
return true;
}
else if (null != root.Right && numbers.Contains(root.Right.Data))
{
numbers.Remove(root.Right.Data);
}
}
return false;
}
}
What is the time complexity ?
You can make this a bit more efficient if you also check if root.val > sum and just return false there because you know you’ll just get more and more negative, assuming they’re all positive integers. That way you cut out all the calls along that path which you know can’t return true. This only work if you only have positive integers, though, since if you allow negative ones you can pull yourself back up to the desired value.
I think it is o(n).
What was your runtime for this solution?
genius
There is another recursive method to solve this problem:
public class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if(root==null) return false;
if(root.val==sum &&(root.left==null && root.right==null))
return true;
return hasPathSum(root.left,sum-root.val) || hasPathSum(root.right,sum-root.val);
}
}