package java_jianzhioffer_algorithm;
/**
* 题目:输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。
* 路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
* (注意: 在返回值的list中,数组长度大的数组靠前)
* @author hexiaoli
* 思考:深度优先搜索。使用前序遍历,定义两个全局变量listAll和list,listAll来存放最终所有路径集合,list用来存放临时路径。每次遍历,先把root的值加入list,目标路径长度减去该值,然后判断当前路径是否同时满足:
1)目标路径长度减到0;
2)左子树为空;
3)右子树为空。
如果满足条件,就将临时路径list加入listAll中,否则,依次遍历左右子树。
PS:遍历左右子树的时候,临时路径list不清空的,直到寻找完毕返回根结点才请空list。
*
*/
import java.util.*;
class TreeNodefp {
int val = 0;
TreeNodefp left = null;
TreeNodefp right = null;
public TreeNodefp(int val) {
this.val = val;
}
}
public class FindPath {
static ArrayList<ArrayList<Integer>> listAll = new ArrayList<>();
static ArrayList<Integer> list = new ArrayList<>();
public static ArrayList<ArrayList<Integer>> findPath(TreeNodefp root,int target){
if(root == null || target < 0) {
return listAll;
}
// 将root值加入临时路径list
list.add(root.val);
// 目标路径长度减去根节点的值
target -= root.val;
// 判断路径是否满足:当前目标路径长度为0;左子树为空;右子树为空。
if( target == 0 && root.left == null && root.right == null) {
// 满足条件则将该条临时路径加入路径集
// 此处add添加的是引用,如果不new,后面的操作会更改这个已经存储完的路径
listAll.add(new ArrayList<Integer>(list));
}
// 不满足条件,递归遍历左子树
findPath(root.left, target);
// 不满足条件,递归遍历左子树
findPath(root.right, target);
// 在该节点下寻找完毕,返回他的父节点
list.remove(list.size() - 1);
return listAll;
}
public static void main(String[] args) {
TreeNodefp root = new TreeNodefp(10);
TreeNodefp left1 = new TreeNodefp(5);
TreeNodefp right1 = new TreeNodefp(12);
TreeNodefp left2 = new TreeNodefp(4);
TreeNodefp right2 = new TreeNodefp(7);
root.left =left1;
root.right=right1;
left1.left=left2;
left1.right=right2;
int target = 22;
findPath(root, target);
for(ArrayList<Integer> list1:listAll) {
Iterator<Integer> it = list1.iterator();
while(it.hasNext()) {
int a = it.next();
System.out.print(a+" ");
}
System.out.println();
}
}
}