Given the root
of a binary tree and an integer targetSum
, determine if there exists a root-to-leaf path such that the sum of all values along the path equals targetSum
.
A leaf is defined as a node with no children.
Example 1: Consider the following binary tree:
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
If targetSum = 22
, the function should return true
because the path 5 -> 4 -> 11 -> 2
sums to 22.
Example 2:
For the tree:
1
/ \
2 3
If targetSum = 5
, the function should return false
because the paths 1 -> 2
(sum is 3) and 1 -> 3
(sum is 4) do not equal 5.
Example 3:
If root = []
(an empty tree) and targetSum = 0
, the function should return false
because there are no root-to-leaf paths.
Constraints:
[0, 5000]
.-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
Write a function to efficiently solve this problem. Consider edge cases like an empty tree or a tree with a single node.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We're given a tree and a target number, and we want to find if there's a path from the top of the tree to a leaf where the numbers along the path add up to the target. The brute force approach explores every single possible path from the top to the bottom of the tree.
Here's how the algorithm would work step-by-step:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def hasPathSumBruteForce(root, targetSum):
if not root:
return False
def pathSumHelper(node, currentSum):
currentSum += node.val
# We have reached a leaf node
if not node.left and not node.right:
return currentSum == targetSum
# Recursively check if the path exists in the left subtree
if node.left:
if pathSumHelper(node.left, currentSum):
return True
# Recursively check if the path exists in the right subtree
if node.right:
if pathSumHelper(node.right, currentSum):
return True
return False
return pathSumHelper(root, 0)
The best way to solve this problem involves exploring the tree in a systematic way while keeping track of the running sum. The core idea is to check, at each step, if we've reached a leaf node and if the current sum matches the target.
Here's how the algorithm would work step-by-step:
class TreeNode:
def __init__(self, value=0, left=None, right=None):
self.value = value
self.left = left
self.right = right
def has_path_sum(root, target_sum):
def path_sum_recursive(node, current_sum):
if not node:
return False
current_sum += node.value
# Check if it's a leaf node.
if not node.left and not node.right:
# If leaf node, compare running sum to target.
if current_sum == target_sum:
return True
else:
return False
# Explore left and right subtrees.
left_path = path_sum_recursive(node.left, current_sum)
right_path = path_sum_recursive(node.right, current_sum)
# Return true if either path is true
return left_path or right_path
return path_sum_recursive(root, 0)
Case | How to Handle |
---|---|
Null or empty tree root | Return false immediately, as there is no path to sum. |
Single node tree where the node's value equals the target sum | Return true, as the single node constitutes a valid path. |
Tree with only one path that sums to target | The algorithm should correctly identify this single valid path. |
Tree with negative node values and a negative target sum | The algorithm should correctly handle negative values and sums, ensuring accurate path calculation. |
Tree with very large positive/negative values that could cause integer overflow when summed | Use long data type to store the intermediate sum during path traversal to avoid integer overflow, if needed. |
Tree with no path that sums to target (all paths exceed or fall short) | The algorithm should traverse all paths and return false if no path equals the target sum. |
Tree with multiple paths that sum to target, only one path is necessary (path existence) | The algorithm should return true upon finding the first valid path. |
Deeply unbalanced tree leading to stack overflow in recursive implementations | Consider iterative DFS or BFS approach with a stack to avoid stack overflow issues with extremely deep trees. |