二叉树和为指定值的路径

494 阅读2分钟

前言

“这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战

  1. NC9 二叉树中是否存在节点和为指定值的路径(简单)
  2. NC8 二叉树根节点到叶子节点和为指定值的路径(中等)

二叉树中是否存在节点和为指定值的路径

描述: 给定一个二叉树和一个值 sum,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径,

思路分析: 定义递归函数 hasPathSum , 处理 base case root 节点为 null 时直接返回 false 即可, 当 root 节点为 叶子节点 且 它的 val 与 sum 相等时, 说明存在一条路径节点之和 等于 sum, 不相等时, 对 root 的左右子树 递归调用此函数, 不过传入的 val 为 sum - root.val

AC 代码:

    public boolean hasPathSum (TreeNode root, int sum) {
        // write code here
        if(root == null){
            return false;
        }
        
        if(root.left == null && root.right == null && root.val == sum){
            return true;
        }
        
        return hasPathSum(root.left, sum - root.val) 
            || hasPathSum(root.right, sum - root.val);
    }

二叉树根节点到叶子节点和为指定值的路径

描述: 给定一个二叉树和一个值 sum,请找出所有的根节点到叶子节点的节点值之和等于 sum 的路径 思路分析: 回溯实现

  1. 已经做出的选择(记录到temp中)
  2. 结束条件(root 为叶子节点时,判断是否时一条符合条件的路径, 是的话就将temp 添加到 res之中)
  3. 当前可以做的选择(递归左右子树) 与上一道题目类似, 只不过这个需要统计节点和等于 sum 的全部路径,

tip : 注意回溯要 在递归调用之前做选择(向 temp 中添加 节点),在递归调用之后撤销选择(移除temp 中刚刚添加的节点) AC 代码:

    ArrayList<ArrayList<Integer>> res ;
    public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
        // write code here
        if(root == null){
            return new ArrayList<>();
        }
        res = new ArrayList<>();
        dfs(root, new ArrayList<>(), sum);
        return res;
    }
    
    void dfs(TreeNode root, ArrayList<Integer> temp, int val){
        
        temp.add(root.val);
        
        // base case
        if(root.left == null && root.right == null && root.val == val){
            res.add(new ArrayList<>(temp));
            return;
        }
        if(root.left != null){
            dfs(root.left, temp, val - root.val);
            temp.remove(temp.size() - 1);
        }
        if(root.right != null){
            dfs(root.right, temp, val - root.val);
            temp.remove(temp.size() - 1);
        }
    }