package club.interview.tree; import club.interview.tree.base.TreeNode; import java.util.ArrayList; import java.util.List; /** * 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。 * fixme https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/ * * 5 * * / * * 4 8 * * / / * * 11 13 4 * * / / * * 7 2 5 1 * * * * 结果如下 * * [ * * [5,4,11,2], * * [5,8,4,5] * * ] * <p> * 知识点扫盲 * 1. 树的前序遍历打印路径 * * @author QuCheng on 2020/6/9. */ public class PathSum { int target = 0; List<List<Integer>> result = new ArrayList<>(); /** * 1. 从根节点开始输出,是前序遍历 * 2. 遍历到叶子节点找到目标值 * 3. 先找到结果的路径,不能影响后续结果 */ public List<List<Integer>> pathSum(TreeNode root, int sum) { target = sum; order(root, 0, new ArrayList<>()); return result; } /** * - 遍历到的节点加入list容器 * - 到叶子节点时比较路径和与目标值,若相等则加入返回值,否则直接返回 * - 因为要到叶子节点才知道是否满足目标和,所以每一个节点都要保存。 * - 但是这样就会存在无效的路径,我们知道每个节点在遍历之后就已经失去了作用,正好在递归方法退出时可以移除节点 */ public void order(TreeNode root, int sum, List<Integer> temp) { if (root == null) { return; } temp.add(root.val); sum = sum + root.val; // 叶子节点判断目标值和累计值是否相等 if (root.left == null && root.right == null) { if (target == sum) { result.add(new ArrayList<>(temp)); } } else { if (root.left != null) { order(root.left, sum, temp); temp.remove(temp.size() - 1); } if (root.right != null) { order(root.right, sum, temp); temp.remove(temp.size() - 1); } } } }