Path Sum
The problem asks for determining whether there exists a root-to-leaf path in a binary tree such that the sum of all the values along the path equals a given target sum. We can solve this problem using recursion.
Here’s the approach:
- Base Case: If the current node is
None
, returnFalse
. It means we have reached a dead end. - Leaf Node Check: If the current node is a leaf node (both left and right children are
None
), we check if the value of the current node equals the remaining target sum. If it does, returnTrue
. - Recursive Calls: Recursively call the function for the left and right children, subtracting the value of the current node from the target sum.
- Result: If either of the recursive calls returns
True
, it means a valid path has been found, and we returnTrue
. If both returnFalse
, then there’s no valid path for the current subtree, and we returnFalse
.
Here’s the code:
|
|
Key Insights:
- The approach follows the Depth-First Search (DFS) pattern.
- The time complexity is (O(n)), where (n) is the number of nodes in the tree, since we visit each node once.
- The space complexity is (O(\log n)) for a balanced tree or (O(n)) for a skewed tree, due to the recursion stack.
|
|
Solution Outline
Recursive Approach
Start at the root
Keep decrementing the path sum
If we reach 0 when we get to the leaf node
Return true
If you never reach 0 for any leaf nodes
Return false
What is the base case?
- What is the smallest instance of the problem?
- If the root is null, return false
What is the unit of work?
- Repeating work at each recursive call (what do we do?) After the base case, check if we have reached the leaf node Check for the condition
We need to perform the unit of work before the recursive call.
We need to make two recursive calls.
True or False is returned from the recursive function 6 If left-subtree || right-subtree return it
5-4-11-7 = 27 It exceeeds. The left subtree in this case will return false 5-4-11-2 = 22 We succeed. The right subtree in this case will return true
|
|
|
|
|
|
Definition for a binary tree node.
class TreeNode
attr_accessor :val, :left, :right
def initialize(val = 0, left = nil, right = nil)
@val = val
@left = left
@right = right
end
end
@param {TreeNode} root
@param {Integer} sum
@return {Boolean}
=begin
How do we make the transition from recursive to iterative?
Differences
- You have to manage the stack programmatically in iterative version
- You have to manage the state programmatically in iterative version
Similarities
- Base case => Edge case
- When we reach the leaf node, we check
- Unit of work
We have to maintain the state as we traverse this tree.
We have to traverse, if we have a right child, if so push it on to the stack if we have a left child, if so push it on to the stack
When do we return true and when do we return false As soon as we find the path sum == sum, return true (early termination) When we have explored all the paths and we have not found any path that adds up to the sum, we return false (outside the loop)
How do we keep track of the running sum?
- We have add it as a pair to the stack
[5, 17] []
[8, 9] [4, 13]
4, 13
[8, 9]
2, 0
=end
def has_path_sum(root, sum) if root.nil? return false end
stack = [[root, sum - root.val]]
while !stack.empty?
node, current_sum = stack.pop
if node.left.nil? and node.right.nil? and current_sum == 0
return true
end
if node.left
stack << [node.left, current_sum - node.left.val]
end
if node.right
stack << [node.right, current_sum - node.right.val]
end
end
return false
end
Definition for a binary tree node.
class TreeNode
attr_accessor :val, :left, :right
def initialize(val = 0, left = nil, right = nil)
@val = val
@left = left
@right = right
end
end
@param {TreeNode} root
@param {Integer} target_sum
@return {Boolean}
def has_path_sum(root, sum)
Base case
if root.nil? return false end
Unit of work
sum -= root.val
Did we hit the leaf node? If so check if the path sum is equal to the given sum
if (root.left.nil? && root.right.nil?) return sum == 0 end
Check the left and right subtrees
has_path_sum(root.left, sum) || has_path_sum(root.right, sum) end
“112. Path Sum” is about determining if a binary tree has a root-to-leaf path such that adding up all the values along the path equals a given target sum.
An isomorphic problem to this could be “437. Path Sum III”. In the “Path Sum III” problem, you are asked to find the number of paths in a binary tree that the sum of the nodes in the path equals a given target sum. The path does not need to start at the root and end at a leaf, but it must move downwards (traveling only from parent nodes to child nodes).
While the “Path Sum III” problem is more generalized, both problems fundamentally require us to find paths in a binary tree based on the sum of the nodes. Both require the use of depth-first search or a similar tree traversal technique to explore all possible paths in the tree. The main difference is that “Path Sum” requires the path to start at the root and end at a leaf, while “Path Sum III” allows for paths to start and end anywhere. However, the techniques used to solve both problems are similar, making them isomorphic at a structural level.
|
|
Problem Classification
Binary Trees: This problem centers around a binary tree, which is a type of data structure in which each node has at most two children, referred to as the left child and the right child.
Tree Traversal: The problem requires understanding of how to traverse a tree, visiting each node in a specific order. In this case, we need to traverse all paths from root to leaves.
Recursion: The problem requires knowledge of recursion, as the solution involves a function calling itself to explore all possible paths in the tree.
Path Sum: This problem involves the concept of a “path sum” in a tree, where the sum is the total of node values along a path from root to leaf.
Decision Making: This problem also involves decision making since you have to make a decision at each node, either go to the left or right child, or end the path if the sum is found or the node is a leaf node.
Language Agnostic Coding Drills
Understanding Binary Trees: This problem involves binary trees. A good understanding of how they work is the first key step.
Recursive Functions: The solution involves recursion, as it dives deeper into each level of the tree.
Path Sum in Trees: The problem involves finding a path from root to leaf that sums to a specific target.
Targeted Drills in Python
- Understanding Binary Trees:
|
|
- Recursive Functions:
|
|
- Path Sum in Trees:
Here, we can introduce the concept of finding a path sum in a binary tree. This drill will involve building a tree, and then writing a recursive function to sum up the values of nodes in a path from root to leaf. We can begin by finding the sum of the path to the leftmost leaf, and then generalize to find all path sums, which will prepare us for the final problem:
|
|
From here, we would need to modify the function to check if the path sum is equal to a given target, which would lead directly to the solution of the original problem.