算法题之求所有从根节点到叶子节点路径总和等于给定目标和的路径问题
题目描述
思路图解
代码实现
方式1
public List<List<Integer>> pathSum(TreeNode root, int sum) {
//定义存储最后结果的list集合
List<List<Integer>> res = new ArrayList<>();
//定义sub存储每一次满足要求的结果集
List<Integer> sub = new ArrayList<>();
findPath(root,sum,res,sub);
//此时res中保存所有满足条件的结果集
return res;
}
private void findPath(TreeNode root, int sum, List<List<Integer>> res, List<Integer> sub) {
if (root == null) {
return;
}
//将当前结点的值加入sub
sub.add(new Integer(root.val));
//判断当前是否到达叶子结点
if (root.left == null && root.right == null) {
if (sum == root.val) {
res.add(new ArrayList<>(sub));
}
//否则移除最后一个元素
sub.remove(sub.size() - 1);
return;
}
//如果没有到达叶子结点
//递归左子树:此时将sum减去root.val
findPath(root.left,sum - root.val,res,sub);
//递归右子树:此时同样将sum减去root.val
findPath(root.right,sum - root.val,res,sub);
//回溯时去掉sub的最后一个值
sub.remove(sub.size() - 1);
}
方式2
public List<List<Integer>> pathSum(TreeNode root, int sum) {
//定义存储最后结果的list集合
List<List<Integer>> res = new ArrayList<>();
//定义sub存储每一次满足要求的结果集
List<Integer> sub = new ArrayList<>();
findPath(root,sum,res,sub);
//此时res中保存所有满足条件的结果集
return res;
}
//方法1:保持sum的值不变:在遍历到达二叉树的叶子结点时,比较sum值和sub中所有的val值得和是否相等
//若相等,则将其加入res结果集中
//若不相等:则去掉最后添加的元素,返回,进行回溯
private void findPath(TreeNode root, int sum, List<List<Integer>> res, List<Integer> sub) {
//当root结点为null直接返回
if (root == null) {
return;
}
//将当前结点的val加入到sub中
sub.add(root.val);
if (root.left == null && root.right == null) {//即到达树的叶子结点
if (getSum(sub) == sum) {
res.add(new ArrayList<>(sub));
}
return;
}
//递归查询该结点的左子树
if (root.left != null) {
findPath(root.left,sum,res,sub);
sub.remove(sub.size() - 1);
}
//递归查询该结点的右子树
if (root.right != null) {
findPath(root.right,sum,res,sub);
sub.remove(sub.size() - 1);
}
}
private int getSum(List<Integer> sub) {
int sum = 0;
for (int i = 0; i < sub.size(); i++) {
sum = sum + sub.get(i);
}
return sum;
}
TreeNode节点类
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}