Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
前言
力扣第113题 路径总和 II 如下所示:
给你二叉树的根节点 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
输出: []
一、思路
经过仔细读题后,我们可以总结一下两个重要的信息:
- 数据结构为
二叉树 - 结果集为
路径和等于目标值得路径
经过前面两题的锻炼,这一题很明显需要使用 递归 来找到所有到叶子节点的路径。
因为在上一题的做法中我就是先通过递归找到所有到叶子节点的路径,在遍历所有的路径,比对路径和与目标值。 这样虽然也能完成这一题,但其实遍历路径和的列表进行比对是没有必要的。
因为我们可以在遍历节点的时候就能知道当前路径是什么以及当前路径的和为多少。
综上所述,递归 中大致的步骤如下所示:
我们可以使用一个int值
val来表示当前路径的和,用栈path来存储当前路径上的节点
- 如当前的节点为空,则返回即可
- 如果当前的节点为叶子节点,会有如下的两种情况:
- 如路径和与目标值相等,则将当前路径加入结果集。再返回
- 反之,则直接返回
- 如果当前节点的左孩子不为空,则以左孩子为根节点,进入递归
- 当前节点的右孩子处理方式同上
tips: 思路中为了更好理解,在看实现代码的时候,有一处需要注意一下:
- 为了减少递归中的参数,实际上
val表示路径和与目标值的差值,当差值val == 0,即他两相等。
二、实现
实现代码
List<List<Integer>> ret = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
allTargetPath(root, targetSum, new Stack<>());
return ret;
}
private void allTargetPath(TreeNode root, int val, Stack<Integer> path){
if (root == null)
return;
path.push(root.val);
val -= root.val;
if (root.left == null && root.right == null){ // 叶子节点
if (val == 0){
ret.add(new ArrayList<>(path));
}
path.pop();
return;
}
if (root.left != null){
allTargetPath(root.left, val, path);
}
if (root.right != null){
allTargetPath(root.right, val, path);
}
path.pop();
}
测试代码
public static void main(String[] args) {
// [5,4,8,11,null,13,4,7,2,null,null,5,1]
TreeNode treeNode = new TreeNode(5,
new TreeNode(4, new TreeNode(11, new TreeNode(7), new TreeNode(2)), null),
new TreeNode(8, new TreeNode(13), new TreeNode(4, new TreeNode(5), new TreeNode(1)))
);
new Number113().pathSum(treeNode, 22);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~