剑指offer-25.二叉树中和为某一值的路径

https://www.nowcoder.com/practice/b736e784e3e34731af99065031301bca?tpId=13&tqId=11177&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking

题目描述
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)

题解:
二叉树中有两条和为22的路径:10、5、7 和 10、12。
这里写图片描述

带记忆的DFS,回溯的时候注意恢复状态。
递归先序遍历的时候,用 list 记录记过的结点,sum 记录路径的和 ,到达叶子结点,判断 sum 是否等于target,满足就加到 result 里。

注意本题递归深度应该为叶子结点,如果到叶子结点的下一级再返回,会出现两个相同的路径。

class Solution {
    ArrayList<ArrayList<Integer>> result = new ArrayList<>();
    ArrayList<Integer> list = new ArrayList<>();

    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
        if (root == null) {
            return result;
        }
        recursive(root, target, 0);
        Comparator<ArrayList<Integer>> comparator = new Comparator<ArrayList<Integer>>() {//从大到小排
            @Override
            public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
                return o2.size() - o1.size();
            }
        };
        Collections.sort(result, comparator);
        return result;
    }

    private void recursive(TreeNode root, int target, int sum) {
        list.add(root.val);
        sum = sum + root.val;
        if (root.left == null && root.right == null) {// 是叶结点
            if(sum == target){//满足条件,则加到result里
                result.add(new ArrayList<Integer>(list)); //一定要再new 一个不然 后面list变了,result里的也跟着变;或者用 clone()
            }
            sum = sum - root.val;//恢复状态
            list.remove(list.size() - 1);
            return;
        }
        //不是叶结点,则遍历子树
        if (root.left != null) {
            recursive(root.left, target, sum);
        }
        if (root.right != null) {
            recursive(root.right, target, sum);
        }
        //恢复状态
        sum = sum - root.val;
        list.remove(list.size() - 1);
    }
}

猜你喜欢

转载自blog.csdn.net/zxm1306192988/article/details/81027778