给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22
,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
[
[5,4,11,2],
[5,8,4,5]
]
解题思路
这个问题和下面这两个问题很类似。
Leetcode 112:路径总和(最详细的解法!!!)
Leetcode 257:二叉树的所有路径(最详细的解法!!!)
当访问的节点是叶子节点
的时候,我们新建一个list
,插入到result
中,然后返回result
。分别遍历左右子树的节点
,然后将他们分别插入到叶子节点
之前就可以了。
class Solution:
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: List[List[int]]
"""
result = list()
if root == None:
return result
if not root.left and not root.right and sum == root.val:
result.append([root.val])
return result
left = self.pathSum(root.left, sum - root.val)
for i in left:
i.insert(0, root.val)
result.append(i)
right = self.pathSum(root.right, sum - root.val)
for i in right:
i.insert(0, root.val)
result.append(i)
return result
我们看看怎么使用迭代来解决这个问题,这里我们和之前问题Leetcode 257:二叉树的所有路径(最详细的解法!!!)
的写法没有太大的差别,无非是string
变成了list
,多了个变量sum
的区别。
class Solution:
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: List[List[int]]
"""
result = list()
if not root:
return result
stack = [(list(), sum, root)]
while stack:
path, val_, node = stack.pop()
if node:
path.append(node.val)
if not node.left and not node.right and val_ == node.val:
result.append(path)
stack += [(path.copy(), val_ - node.val, node.left), (path.copy(), val_ - node.val, node.right)]
return result
这里我们要注意path.copy()
,这是因为string
是一个不可变类型,它是通过值传递,而list
是一个可变类型,它是通过引用传递,如果想要list
通过值传递的话,就必须使用copy
。
这个问题的第一种递归实现cpp
版本,有一些陷阱,可以参考我的实现。
class Solution
{
public:
vector<vector<int>> pathSum(TreeNode* root, int sum)
{
vector<vector<int>> result;
if (root == nullptr) return result;
if (root->left == nullptr and root->right == nullptr and sum == root->val)
{
result.push_back(vector<int>(1, root->val));// 1
return result;
}
vector<vector<int>> left = pathSum(root->left, sum - root->val);
for (auto& i : left)
{
i.insert(i.begin(), 1, root->val);// 2
result.push_back(i);
}
vector<vector<int>> right = pathSum(root->right, sum - root->val);
for (auto& i : right)
{
i.insert(i.begin(), 1, root->val);
result.push_back(i);
}
return result;
}
};
所以递归的话,我这里更推荐你使用下面回溯
的方式去写。
class Solution:
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: List[List[int]]
"""
result = list()
if not root:
return result
self._pathSum(result, list(), root, sum)
return result
def _pathSum(self,result, path, node, num):
if node:
path.append(node.val)
if not node.left and not node.right and num == node.val:
result.append(path.copy())
self._pathSum(result, path, node.left, num - node.val)
self._pathSum(result, path, node.right, num - node.val)
path.pop()
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!