题目描述
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
import java.util.ArrayList;
/**
* 思路分析:首先思考节点值的和为输入的整数,每条路径都一定是从根节点到叶子节点,在数据结构中从根节点到叶子节点的遍历称之为深度优先遍历DFS。
* 因此整个过程可以采用先序遍历方式的DFS,即根节点》左子树》右子树。随后考虑一次遍历完成后的处理,当一次遍历完成后,如果输入整数值恰好等于节
* 点值之和,则输出这条路径并且回退一个节点;如果不等于则直接回退一个节点,即回退到当前节点的父节点,如果该父节点有右孩子,则继续遍历,否则继续
* 回退。考虑回退到根节点,此时如果它有右孩子,则继续遍历,否则整个DFS结束。
* 数据结构分析:使用java完成整个题目,采用ArrayList<ArrayList<Integer>>,举个如下的例子,输入整数为22。
* 第一次遍历 10,5,4 19<22,因此ArrayList要使用remove函数回退到父节点5上,开始寻找右孩子。
* 第二次遍历 10,5,7
* 22=22,此时正好输出这条路径(将路径添加到ArrayList中),10,5,7,回退到父节点5上,此时5的左右孩子都已遍历完成,因此回退到父节点10
* 第三次遍历 10,12
* 22=22,此时正好输出这条路径(将路径添加到ArrayList中),10,12,由于12没有左右孩子,因此直接回退到父节点10
*
* 由于根节点10左右孩子都已遍历完成,因此整个DFS结束。
*
* 需要注意的是不论路径的值是否等于输入整数值,都要回退,即使用remove函数移除路径上的最后一个节点。
*/
class Solution24 {
private ArrayList<ArrayList<Integer>> listAll = new ArrayList<ArrayList<Integer>>();
private ArrayList<Integer> list = new ArrayList<Integer>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
if (root == null)
return listAll;
// 把当前节点添加进集合
list.add(root.val);
target -= root.val;
if (target == 0 && root.left == null && root.right == null)
// 不重新new的话从始至终listAll中所有引用都指向了同一个一个list
listAll.add(new ArrayList<Integer>(list));
FindPath(root.left, target);
FindPath(root.right, target);
// 递归到叶子节点如果还没有找到路径,就要回退到父节点继续寻找,依次类推
list.remove(list.size() - 1);
return listAll;
}
}
public class TestDemo24 {
public static void main(String[] args) {
TreeNode root = new TreeNode(10);
root.left = new TreeNode(5);
root.right = new TreeNode(12);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(7);
root.left.left.left = new TreeNode(3);
root.left.left.right = new TreeNode(5);
Solution24 sol = new Solution24();
ArrayList<ArrayList<Integer>> lists = sol.FindPath(root, 22);
for (int i = 0; i < lists.size(); i++) {
System.out.println(lists.get(i));
}
}
}
//运行结果
[10, 5, 4, 3]
[10, 5, 7]
[10, 12]