持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
题目
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
示例 2
输入:root = [1,2,3], targetSum = 5
输出:[]
示例 3
输入:root = [1,2], targetSum = 0
输出:[]
提示
- 树中节点总数在范围 [0, 5000] 内
- -1000 <= Node.val <= 1000
- -1000 <= targetSum <= 1000
题解
思路
我们只需要从根节点开始持续计算当前路径的总和,并同时记录路径中都有哪些节点。然后往左右子树递归遍历,直到叶子节点时判断当前路径总和是否等于目标数,如果是的话,把当前路径放入结果集合中就结束递归直接返回。
通过以上分析我们就可以得出以下递归的三个要素了:
- 终止条件
- 当前节点为null就终止了
- 递归函数做的事情是什么以及如何去做
- 把当前节点加入到record路径中。
- 当到达叶子节点时,如果路径和等于目标路径,需要把record加入到结果集合中,然后返回。
- 返回前需要把当前节点从record路径中移除。
- 重复利用递归函数。
- 函数最终返回前需要把当前节点从record路径中移除。
- 如何重复利用递归函数
- 递归调用当前函数,从左右子树中去寻找目标路径和。
下面代码实现中的递归函数其实与二叉树的先序遍历很类似,当然使用中序遍历和后续遍历也是可以的。题目重点与访问节点的先后顺序无关,而是计算从根节点到当前路径的总和。
代码
class Solution {
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
pathSum(root, targetSum, 0, new ArrayList<>());
return result;
}
public void pathSum(TreeNode root, int targetSum, int sum, List<Integer> record) {
if (root == null) {
return;
}
record.add(root.val);
sum = sum + root.val;
if (root.left == null && root.right == null && targetSum == sum) {
result.add(new ArrayList<>(record));
record.remove(record.size()-1);
return;
}
pathSum(root.left, targetSum, sum, record);
pathSum(root.right, targetSum, sum, record);
record.remove(record.size()-1);
}
}
结语
业精于勤,荒于嬉;行成于思,毁于随。