问题描述
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
[
[5,4,11,2],
[5,8,4,5]
]
思路
就DFS就可以了。只不过返回的数据是对象,所以要进行状态回退。并且在加入结果的时候要new一个新对象,否则的话结果集中的结果就是都一样的。
方法一是每次往下遍历都复制出来一个新的arrayList.
方法二是只有符合题意的时候才复制一份儿新的arrayList。
可想而知,方法二效率更高。
方法一
Java版
class Solution {
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
pathSum(root,sum,new ArrayList<>());
return res;
}
private void pathSum(TreeNode root, int sum, ArrayList<Integer> cur){
if(root == null) return;
sum -= root.val; // 统计sum
cur.add(root.val);
if(root.left == null && root.right == null){
// 叶子
if(sum == 0){
// 满足题意
res.add(cur);
}
return;
}
ArrayList<Integer> next = new ArrayList<>();
next = (ArrayList<Integer>) cur.clone();
pathSum(root.left,sum,next);
// next已经被左子树的递归污染了,所以要重新复制
next = (ArrayList<Integer>) cur.clone();
pathSum(root.right,sum,next);
}
}
方法二
Java版
class Solution {
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
pathSum1(root,sum,new ArrayList<>());
return res;
}
private void pathSum1(TreeNode root, int sum, ArrayList<Integer> cur){
if(root == null) return;
cur.add(root.val);
sum -= root.val;
if(root.left == null && root.right == null){
if(sum == 0){
res.add(new ArrayList<>(cur)); // 只在符合条件新增,省时间
}
cur.remove(cur.size()-1); // 状态回退
return;
}
pathSum1(root.left,sum,cur);
pathSum1(root.right,sum,cur);
cur.remove(cur.size()-1);
}
}