LeetCode 112 路径总和
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-sum
题意:
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。
示例 3:
输入:root = [], targetSum = 0
输出:false
解释:由于树是空的,所以不存在根节点到叶子节点的路径。
提示:
树中节点的数目在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
思路:
递归法:
递归法写到最后代码可以说是非常的简洁,也很容易理解。如果不理解可以看参考文章中写的,说明的很详细
本题Java代码:
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null)
return false;
if (root.left == null && root.right == null && targetSum == root.val)
return true;
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}
}
LeetCode 113 路径总和II
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-sum-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
输出:[]
示例 3:
输入:root = [1,2], targetSum = 0
输出:[]
提示:
树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
思路:
这道题其实跟上一道题是很相似的,只是他需要将这些符合要求的路径输出出来。我在这里采用的跟之前的《LeetCode 257 二叉树的所有路径》的方法是类似的,都是在递归方法的参数中加入当前遍历的序列,只不过在这里将String类型换成了List类型。
只要将上一道题的递归法理解之后,这道题仅仅只是在递归方法中多加个参数而已,而且由于这道题需要遍历二叉树所有的路径且并不仅仅只是返回一个boolean变量,因此在这道题我们的递归方法返回值设为了void,并用一个全局变量ans来记录答案。
需要注意的是: 记住在List变量ans中加入List变量path,加入的是path的引用,即地址值,那么如果这个path变量在其他地方变动了,也会导致ans中的元素对应改变。这样是为什么以下代码中在每次调用递归方法时都重新new一个ArrayList的原因,这样子进行一个List变量的拷贝,才能在每个递归方法中都是一个新的path变量,切记在这里调用递归方法时不是直接把当前递归方法中的实参path变量传入!
如果说要直接传入实参path变量的话也是可以的,记得每次回溯要把path中最后一个元素删掉!
以下提供这两种做法的代码:
每次调用递归方法都重新new一个ArrayList变量的方法 Java代码:
class Solution {
private List<List<Integer>> ans;
private void search(TreeNode node, int targetSum, List<Integer> path) {
if (node == null)
return;
path.add(node.val);
if (node.left == null && node.right == null && targetSum == node.val) {
ans.add(path);
return;
}
search(node.left, targetSum - node.val, new ArrayList(path));
search(node.right, targetSum - node.val, new ArrayList(path));
}
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
ans = new ArrayList<>();
search(root, targetSum, new ArrayList<>());
return ans;
}
}
每次调用递归方法直接传入当前递归方法的path实参 Java代码:
class Solution {
private List<List<Integer>> ans;
private void search(TreeNode node, int targetSum, List<Integer> path) {
if (node == null)
return;
path.add(node.val);
if (node.left == null && node.right == null && targetSum == node.val) {
List<Integer> tmp = new ArrayList(path);
ans.add(tmp);
path.remove(path.size() - 1);//记得删掉最后一个元素
return;
}
search(node.left, targetSum - node.val, path);
search(node.right, targetSum - node.val, path);
path.remove(path.size() - 1);//记得删掉最后一个元素
}
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
ans = new ArrayList<>();
search(root, targetSum, new ArrayList<>());
return ans;
}
}