第二十三题:二叉树中和为某一值的路径
题目描述
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
思路:
DFS(深度优先遍历)
1. 从根节点出发,记录每条到叶子节点的路径
2. 每走过一个节点并将target -= node.val
3. 到达叶子节点进行判断。target与叶子节点相等,则将该条路径记录的值添加到结果集中。
注意:
①递归结束的条件(左孩子与右孩子节点不为null && node.val等于target)
②创建新的ArrayList进行存储已经走过的路径(备份,当该路径不能走通,用于回退到叶子节点的父节点)
③左子树继续查找,右子树进行重新查找
具体实现如下图所示:
具体实现代码如下:
//递归
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
//存储结果集
ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
//代码的鲁棒性
if (root == null){
return lists;
}
//查找方法
find(lists,new ArrayList<>(),root,target);
//返回结果集
return lists;
}
//查找
public void find(ArrayList<ArrayList<Integer>> lists,
ArrayList<Integer> list,TreeNode root,int target){
//将根节点加入到list
list.add(root.val);
//递归的结束条件
if (root.left == null && root.right == null){
//当target与叶子节点相等时,结束本次递归
if (root.val == target){
lists.add(list);
}
return;
}
//创建新的ArrayList存储已经走过的路径
ArrayList<Integer> list1 = new ArrayList<>();
//并且将走过路径的所有值存储到list1
list1.addAll(list);
//左孩子树继续查找查找,递归操作
if(root.left != null)
find(lists,list,root.left,target-root.val);
//右孩子树重新查找
if(root.right != null)
find(lists,list1,root.right,target-root.val);
}
//回溯
//存储结果集
private ArrayList<ArrayList<Integer>> res = new ArrayList<>();
//存储每一条路径的结果
private ArrayList<Integer> list = new ArrayList<>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
//代码的鲁棒性
if(root == null)
return res;
list.add(root.val);
target -= root.val;
//递归的结束条件
if(target == 0 && root.left == null && root.right == null) {
// 创建新的ArrayList存储查找路径成功的结果
res.add(new ArrayList<Integer>(list));
}
//左右孩子树递归
FindPath(root.left, target);
FindPath(root.right, target);
//回溯 如果到了叶子节点 发现target不等于0 说明该路径不是最终的结果集之一
//此时回溯到叶子节点的父节点,并且继续递归。依次类推
list.remove(list.size() - 1);
return res;
}