Welcome to Subscribe On Youtube
113. Path Sum II
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.
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: []
Constraints:
- The number of nodes in the tree is in the range
[0, 5000]
. -1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
Solutions
Solution 1: DFS
We start from the root node, recursively traverse all paths from the root node to the leaf nodes, and record the path sum. When we traverse to a leaf node, if the current path sum equals targetSum
, then we add this path to the answer.
The time complexity is $O(n^2)$, where $n$ is the number of nodes in the binary tree. The space complexity is $O(n)$.
-
/** * 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 List<List<Integer>> ans = new ArrayList<>(); private List<Integer> t = new ArrayList<>(); public List<List<Integer>> pathSum(TreeNode root, int targetSum) { dfs(root, targetSum); return ans; } private void dfs(TreeNode root, int s) { if (root == null) { return; } s -= root.val; t.add(root.val); if (root.left == null && root.right == null && s == 0) { ans.add(new ArrayList<>(t)); } dfs(root.left, s); dfs(root.right, s); t.remove(t.size() - 1); } }
-
/** * 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 { public: vector<vector<int>> pathSum(TreeNode* root, int targetSum) { vector<vector<int>> ans; vector<int> t; function<void(TreeNode*, int)> dfs = [&](TreeNode* root, int s) { if (!root) return; s -= root->val; t.emplace_back(root->val); if (!root->left && !root->right && s == 0) ans.emplace_back(t); dfs(root->left, s); dfs(root->right, s); t.pop_back(); }; dfs(root, targetSum); return ans; } };
-
# 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 class Solution: def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]: def dfs(root, s): if root is None: return s += root.val t.append(root.val) if root.left is None and root.right is None and s == targetSum: ans.append(t[:]) dfs(root.left, s) dfs(root.right, s) t.pop() ans = [] t = [] dfs(root, 0) return ans
-
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */ func pathSum(root *TreeNode, targetSum int) (ans [][]int) { t := []int{} var dfs func(*TreeNode, int) dfs = func(root *TreeNode, s int) { if root == nil { return } s -= root.Val t = append(t, root.Val) if root.Left == nil && root.Right == nil && s == 0 { ans = append(ans, slices.Clone(t)) } dfs(root.Left, s) dfs(root.Right, s) t = t[:len(t)-1] } dfs(root, targetSum) return }
-
/** * 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 ans = []; const t = []; function dfs(root, s) { if (!root) return; s -= root.val; t.push(root.val); if (!root.left && !root.right && s == 0) ans.push([...t]); dfs(root.left, s); dfs(root.right, s); t.pop(); } dfs(root, targetSum); return ans; };
-
// Definition for a binary tree node. // #[derive(Debug, PartialEq, Eq)] // pub struct TreeNode { // pub val: i32, // pub left: Option<Rc<RefCell<TreeNode>>>, // pub right: Option<Rc<RefCell<TreeNode>>>, // } // // impl TreeNode { // #[inline] // pub fn new(val: i32) -> Self { // TreeNode { // val, // left: None, // right: None // } // } // } use std::rc::Rc; use std::cell::RefCell; impl Solution { fn dfs( root: Option<Rc<RefCell<TreeNode>>>, paths: &mut Vec<i32>, mut target_sum: i32, res: &mut Vec<Vec<i32>> ) { if let Some(node) = root { let mut node = node.borrow_mut(); target_sum -= node.val; paths.push(node.val); if node.left.is_none() && node.right.is_none() { if target_sum == 0 { res.push(paths.clone()); } } else { if node.left.is_some() { Self::dfs(node.left.take(), paths, target_sum, res); } if node.right.is_some() { Self::dfs(node.right.take(), paths, target_sum, res); } } paths.pop(); } } pub fn path_sum(root: Option<Rc<RefCell<TreeNode>>>, target_sum: i32) -> Vec<Vec<i32>> { let mut res = vec![]; let mut paths = vec![]; Self::dfs(root, &mut paths, target_sum, &mut res); res } }