题目描述
输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
题解
采用dfs思想,进行深度优先遍历,用一个ArrayList存储当前路径,另一个ArrayList存储满足条件的路径。
每当进入一个节点,就向当前路径添加当前节点,随后计算此节点及遍历其子节点。
题目中的意思是只有当走到叶子节点时的list才是一个路径,因此每次都判断是否是叶子节点,以及此路径是否满足要求。
当此节点及其子节点都遍历完之后,就在当前路径的ArrayList中删除掉此节点,继续遍历其他节点。知道全部遍历完为止。
需要注意的是,题目要求数组长度大的数组靠前。只靠遍历实现似乎没有很好的办法,最简单的办法是对ArrayList做一个按数组长度进行的排序,可以使用ArrayList的排序方法sort(Comparator<? super E> c)
来实现,需传入一个Comparator的匿名内部类。这里我采用了Java 8里面的新特性 - lambda表达式来实现。不太熟悉的同学们可以学习一下它的使用:Lambda表达式的使用
牛客的样例貌似默认都是完全二叉树,不要排序也能A。。为
下面上代码:
import java.util.*;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
private ArrayList<Integer> list = new ArrayList();
private ArrayList<ArrayList<Integer>> listAll = new ArrayList();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
if( root == null ){
return listAll;
}
list.add(root.val); //将当前节点添加进当前路径
target -= root.val;
//这个判断的意思是:如果当前root节点是叶子节点,且当前list的路径和 = target
if( target==0 && root.left==null && root.right==null ){
//将当前路径添加。这里要new一个list,否则listAll存储的都是对list的引用
//我们要的是存储的都是分配了内存的ArrayList数组
listAll.add(new ArrayList<Integer>(list));
}
//否则的话就遍历左孩子和右孩子
FindPath(root.left, target);
FindPath(root.right, target);
//遍历完当前root及其子节点之后回退节点,遍历其他路径
list.remove(list.size()-1);
//使用comparator,使数组长度大的靠前
listAll.sort( (ArrayList<Integer> a, ArrayList<Integer> b) ->
Integer.compare(b.size(), a.size()));
return listAll;
}
}