文章目录
- 13.路径总和
- 13.1问题
- 13.2解法一:递归
- 13.2.1递归思路
- (1)确定递归函数参数以及返回值
- (2)确定终止条件
- (3)确定递归逻辑
- 13.2.2代码实现
- 14.路径总和 ||
- 14.1问题
- 14.2解法一:递归
- 14.2.1递归思路
- (1)确定递归函数参数以及返回值
- (2)确定终止条件
- (3)确定递归逻辑
- 14.2.2代码实现
13.路径总和
13.1问题
给你二叉树的根节点 root
和一个表示目标和的整数 targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum
。如果存在,返回 true
;否则,返回 false
。
叶子节点 是指没有子节点的节点。
- 示例一:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。
13.2解法一:递归
13.2.1递归思路
(1)确定递归函数参数以及返回值
- 参数:节点、计数器(记录从根节点到该节点的值)、targetSum
- 返回值:需要搜索整棵二叉树并且需要处理递归返回值的递归函数就需要返回值,此题使用boolean代表这颗树是否存在路径总和为targetSum的路径
private boolean traversal(TreeNode node,int count,int targetSum)
(2)确定终止条件
- 当当前节点为叶子节点并且count=targetSum时,返回true(该count已经包含当前节点的值了);
- 当当前节点为叶子节点,直接返回false
if(node.left==null && node.right==null && count==targetSum){
return true;
}
if(node.left==null && node.right==null){
return false;
}
(3)确定递归逻辑
- 因为终止条件是判断叶子节点,所以递归的过程中就不要让空节点进入递归了;
- 若该节点的左右孩子非空,则递归(注意递归函数的count加上左右孩子的值);
- 递归完若发现为true,则直接返回true,否则进行回溯,不要该左孩子节点(count减去该值),进行右孩子节点的查找(回溯);
if(node.left!=null){
if(traversal(node.left,count+=node.left.val,targetSum)){
return true;
}
//回溯
count-=node.left.val;
}
if(node.right!=null){
if(traversal(node.right,count+=node.right.val,targetSum)){
return true;1
}
//回溯
count-=node.right.val;
}
return false;
13.2.2代码实现
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root==null){
return false;
}
return traversal(root,root.val,targetSum);
}
private boolean traversal(TreeNode node,int count,int targetSum){
if(node.left==null && node.right==null && count==targetSum){
return true;
}
if(node.left==null && node.right==null){
return false;
}
if(node.left!=null){
if(traversal(node.left,count+=node.left.val,targetSum)){
return true;
}
//回溯
count-=node.left.val;
}
if(node.right!=null){
if(traversal(node.right,count+=node.right.val,targetSum)){
return true;
}
//回溯
count-=node.right.val;
}
return false;
}
}
14.路径总和 ||
14.1问题
给你二叉树的根节点 root
和一个整数目标和 targetSum
,找出所有 从根节点到叶子节点 路径总和等于给定目标和 的路径。
叶子节点 是指没有子节点的节点。
- 示例一:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
14.2解法一:递归
14.2.1递归思路
(1)确定递归函数参数以及返回值
- 参数说明:
- 求根节点到 node 节点的路径之和 == targetSum
- paths存放当前路径
- res存放符合路径总和为targetSum的路径
- count代表从根节点到该节点的路径中和
- 无返回值
private void traversal(TreeNode node, List<Integer> paths, List<List<Integer>> res, int count, int targetSum)
(2)确定终止条件
- 若该节点为叶子节点,则判断count==targetSum,符合则添加该paths到res中,否则返回
if(node.left==null && node.right==null){
if(count==targetSum) {
res.add(new ArrayList<>(path));
}
return;
}
(3)确定递归逻辑
if(node.left!=null){
paths.add(node.left.val);
traversal(node.left,paths,res,count+=node.left.val,targetSum);
//回溯
paths.remove(paths.size()-1);
count-=node.left.val;
}
if(node.right!=null){
paths.add(node.right.val);
traversal(node.right,paths,res,count+=node.right.val,targetSum);
//回溯
paths.remove(paths.size()-1);
count-=node.right.val;
}
14.2.2代码实现
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
int count=0;
List<List<Integer>> res=new ArrayList<>();
List<Integer> paths=new ArrayList<>();
if(root==null){
return res;
}
paths.add(root.val);
traversal(root,paths,res,count+=root.val,targetSum);
return res;
}
private void traversal(TreeNode node, List<Integer> paths, List<List<Integer>> res, int count, int targetSum){
if(node.left==null && node.right==null){
if(count==targetSum){
res.add(new ArrayList<>(paths));
}
return;
}
if(node.left!=null){
paths.add(node.left.val);
traversal(node.left,paths,res,count+=node.left.val,targetSum);
//回溯
paths.remove(paths.size()-1);
count-=node.left.val;
}
if(node.right!=null){
paths.add(node.right.val);
traversal(node.right,paths,res,count+=node.right.val,targetSum);
//回溯
paths.remove(paths.size()-1);
count-=node.right.val;
}
}
}