Problem Description
Given the root of a binary tree and an integer targetSum, return all root-to-leaf paths where the sum of the node values in the path equals targetSum. Each path should be returned as a list of the node values, not node references.
A root-to-leaf path is a path starting from the root and ending at any leaf node. A leaf is a node with no children.
Examples
Example 1: Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 Output: [[5,4,11,2],[5,8,4,5]] Explanation: There are two paths whose sum equals targetSum: 5 + 4 + 11 + 2 = 22 5 + 8 + 4 + 5 = 22 Example 2: Input: root = [1,2,3], targetSum = 5 Output: [] Example 3: Input: root = [1,2], targetSum = 0 Output: []
Python Solution
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
def pathSum(root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
def dfs(node: Optional[TreeNode], remaining: int, path: List[int], result: List[List[int]]) -> None:
if not node:
return
# Add current node to path
path.append(node.val)
# Check if it's a leaf node and sum matches
if not node.left and not node.right and remaining == node.val:
result.append(path[:]) # Make a copy of the path
# Recursively check left and right subtrees
dfs(node.left, remaining - node.val, path, result)
dfs(node.right, remaining - node.val, path, result)
# Backtrack by removing current node
path.pop()
result = []
dfs(root, targetSum, [], result)
return result
Java Solution
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private void dfs(TreeNode node, int remaining, List path, List> result) {
if (node == null) {
return;
}
// Add current node to path
path.add(node.val);
// Check if it's a leaf node and sum matches
if (node.left == null && node.right == null && remaining == node.val) {
result.add(new ArrayList<>(path)); // Make a copy of the path
}
// Recursively check left and right subtrees
dfs(node.left, remaining - node.val, path, result);
dfs(node.right, remaining - node.val, path, result);
// Backtrack by removing current node
path.remove(path.size() - 1);
}
public List> pathSum(TreeNode root, int targetSum) {
List> result = new ArrayList<>();
dfs(root, targetSum, new ArrayList<>(), result);
return result;
}
}
C++ Solution
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
void dfs(TreeNode* node, int remaining, vector& path, vector>& result) {
if (!node) {
return;
}
// Add current node to path
path.push_back(node->val);
// Check if it's a leaf node and sum matches
if (!node->left && !node->right && remaining == node->val) {
result.push_back(path); // Vector will be copied
}
// Recursively check left and right subtrees
dfs(node->left, remaining - node->val, path, result);
dfs(node->right, remaining - node->val, path, result);
// Backtrack by removing current node
path.pop_back();
}
public:
vector> pathSum(TreeNode* root, int targetSum) {
vector> result;
vector path;
dfs(root, targetSum, path, result);
return result;
}
};
JavaScript Solution
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} targetSum
* @return {number[][]}
*/
var pathSum = function(root, targetSum) {
const dfs = (node, remaining, path, result) => {
if (!node) {
return;
}
// Add current node to path
path.push(node.val);
// Check if it's a leaf node and sum matches
if (!node.left && !node.right && remaining === node.val) {
result.push([...path]); // Make a copy of the path
}
// Recursively check left and right subtrees
dfs(node.left, remaining - node.val, path, result);
dfs(node.right, remaining - node.val, path, result);
// Backtrack by removing current node
path.pop();
};
const result = [];
dfs(root, targetSum, [], result);
return result;
};
C# Solution
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
public class Solution {
private void Dfs(TreeNode node, int remaining, IList path, IList> result) {
if (node == null) {
return;
}
// Add current node to path
path.Add(node.val);
// Check if it's a leaf node and sum matches
if (node.left == null && node.right == null && remaining == node.val) {
result.Add(new List(path)); // Make a copy of the path
}
// Recursively check left and right subtrees
Dfs(node.left, remaining - node.val, path, result);
Dfs(node.right, remaining - node.val, path, result);
// Backtrack by removing current node
path.RemoveAt(path.Count - 1);
}
public IList> PathSum(TreeNode root, int targetSum) {
IList> result = new List>();
Dfs(root, targetSum, new List(), result);
return result;
}
}
Complexity Analysis
- Time Complexity: O(n²) where n is the number of nodes in the tree
- Space Complexity: O(h) where h is the height of the tree
Solution Explanation
This solution uses DFS with backtracking:
- Key concept:
- Path tracking
- Sum tracking
- Backtracking
- Algorithm steps:
- Add nodes to path
- Check leaf nodes
- Backtrack path
- Collect results
Key points:
- Path maintenance
- Proper backtracking
- Result collection
- Memory efficiency