剑指Offer 34、二叉树中和为某一值的路径

121 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情

题目:给定二叉树的根节点root和一个目标值target,要求找出所有从根节点到叶子节点的路径总和等于给定目标的路径和。

解题思路

本题限定了必须从根节点到叶子节点,其实变相的将题目简单化了,见过一题是不要求从根节点出发且不需要以叶子节点结束,找到存在的路径即可。那题的思路是将所有节点都当作根节点,之后以此根节点一个个节点进行判断即可。并且考虑到计算所有节点时会产生很多重复计算,因此在每次遍历的时候都使用map提前将已有的情况保存下来,之后直接判断即可得到最终的结果,使用的是前缀和的思想。

本题的思路还是递归,我们可以从头往下找,每次都更新target的值,直到最终的target等于0的时候判断是否为根节点即可,需要注意的是二叉树的回溯以及结果的保存。首先看代码:

private ArrayList<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int target) {
    dfs(root, target, new ArrayList<>());
    return res;
}

public void dfs(TreeNode root, int target, List<Integer> temp){
    if(root==null) return;
    temp.add(root.val);
    int cur = target-root.val;
    if(cur==0&&root.left==null&&root.right==null){
        res.add(new ArrayList<>(temp));
    }
    dfs(root.left, cur, temp);
    dfs(root.right, cur, temp);
    temp.remove(temp.size()-1);
}

在得到的结果满足条件的时候,我们不能简单的将临时结果保存到最终结果中,因为此时ArrayList保存的只是链表的引用,如果链表进行修改,则里面的内容也会发生修改,应该将已有的结果转为一个新的对象进行保存。并且在每次递归完成后都需要进行回溯,否则最终的链表会保存递归到的所有节点。