题目:二叉树从root到叶子节点的path称为路径。把所有路径和为sum的路径保存到list当中返回。返回结果为List<List>类型。
public List<List> pathSum(TreeNode root, int sum)
思路:递归模拟遍历,把符合的路径保存。
注意:
-
List变量一般只能放到类属性中,无法放到递归方法的参数中(因为list传递的是引用,无法用递归来回退)
-
用List<List>来保存list时,需要创建list实体然后再保存,如:result.add(new ArrayList<>(resList))。否则保存不住。
-
二叉树递归时,可以直接写recur(root.left)和recur(root.right)然后在下一层递归时来判断是否为null来简化代码。
-
当然这种也不一定会简化代码,具体问题具体分析。
主体:
/*
像递归保存list,这list只能作为类属性变量
像保存list然后返回,需要创建list实体,new ArrayList<>(list)(因为list为引用)
*/
private List<List<Integer>> result = new ArrayList<>();
private List<Integer> resList = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
if(root == null) return result;
recur(root,sum);
return result;
}
优化前:
//List不能作为递归的参数,因为传递的是引用,会一直add,不会回退
public void recur(TreeNode root, int sum) {
resList.add(root.val);
//当路径和不为sum时,就return;,然后上一个resList里是没有这个不符合sum的叶子结点的
if(root.left == null && root.right == null){
//因为list为引用,所以add的时候需要再创建个实体。 new ArrayList<>(resList)
if(sum - root.val == 0) result.add(new ArrayList<>(resList));
//手动删除
resList.remove(resList.size()-1);
return;
}
if(root.left != null) recur(root.left,sum - root.val);
if(root.right != null) recur(root.right,sum - root.val);
//如果只是引用这最后递归结束时所有节点都被删除了
//手动删除,来往上回溯
resList.remove(resList.size()-1);
}
优化后:
/*
可以让root为null,然后多几层递归来简化代码
比如:不写!=null,而在下一层递归中解决null的问题
*/
public void recur2(TreeNode root, int sum) {
if(root == null) return;
resList.add(root.val);
if(root.left == null && root.right == null){
if(sum - root.val == 0) result.add(new ArrayList<>(resList));
}
recur2(root.left,sum - root.val);
recur2(root.right,sum - root.val);
resList.remove(resList.size()-1);
}