首页 > 其他分享 >【二叉树】Leetcode 437. 路径总和 III【中等】

【二叉树】Leetcode 437. 路径总和 III【中等】

时间:2024-04-01 13:32:25浏览次数:22  
标签:right TreeNode root targetSum 二叉树 new 437 III left

路径总和 III

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

示例1:
在这里插入图片描述
**输入:**root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
**输出:**3
**解释:**和等于 8 的路径有 3 条,如图所示。

解题思路

可以使用深度优先搜索(DFS)进行解决。

  • 1、对于每个节点,可以该节点作为起点,向下递归搜索路径,并计算路径和是否等于目标和 targetSum。
  • 2、对于每个节点,计算从该节点开始的路径中和为目标和targetSum的路径数量。
  • 3、对于每个节点,分别计算从左子树和右子树开始的路径中和为目标和targetSum的路径数量。
  • 4、最终结果为当前节点路径数量加上左子树路径数量和右子树路径数量的总和。

Java实现(int类型大数会有计算溢出问题过不了leetcode官方测试)

public class PathSumIII {

    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int val) {
            this.val = val;
        }
    }

    public int pathSum(TreeNode root, int targetSum) {
        if (root == null) {
            return 0;
        }

        // 从当前节点开始的路径数目 + 从左子树开始的路径数目 + 从右子树开始的路径数目
        return countPath(root, targetSum) + pathSum(root.left, targetSum) + pathSum(root.right, targetSum);
    }

    //计算该节点符合路径数
    private int countPath(TreeNode node, int targetSum) {
        if (node == null) {
            return 0;
        }

        int count = 0;
        if (node.val == targetSum) {
            count++;
        }

        count += countPath(node.left, targetSum - node.val);
        count += countPath(node.right, targetSum - node.val);

        return count;
    }

    // 示例测试
    public static void main(String[] args) {
        PathSumIII solution = new PathSumIII();

//                 10
//                /  \
//               5   -3
//               / \    \
//              3   2   11
//             / \
//            3  -2
//                /
//               1
        // 构造二叉树
        TreeNode root = new TreeNode(10);
        root.left = new TreeNode(5);
        root.right = new TreeNode(-3);
        root.left.left = new TreeNode(3);
        root.left.right = new TreeNode(2);
        root.right.right = new TreeNode(11);
        root.left.left.left = new TreeNode(3);
        root.left.left.right = new TreeNode(-2);
        root.left.right.right = new TreeNode(1);

        int targetSum = 8;
        System.out.println(solution.pathSum(root, targetSum)); // 输出 3
    }
}

Java实现2(节点计算时转为long类型计算)

public class PathSumIII {

    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int val) {
            this.val = val;
        }
    }

    public int pathSum(TreeNode root, int targetSum) {
        if (root == null) {
            return 0;
        }

        // 从当前节点开始的路径数目 + 从左子树开始的路径数目 + 从右子树开始的路径数目
        return countPath(root, (long) targetSum) + pathSum(root.left, targetSum) + pathSum(root.right, targetSum);
    }

    //计算该节点符合路径数
    private int countPath(TreeNode node, long targetSum) {
        if (node == null) {
            return 0;
        }

        int count = 0;
        if (node.val == targetSum) {
            count++;
        }
        //leetcode 官方测试案例会溢出不过,targetSum和node.val 改为long进行计算

        long longNodeValue = node.val;
        count += countPath(node.left, targetSum - longNodeValue);
        count += countPath(node.right, targetSum - node.val);

        return count;
    }

    // 示例测试
    public static void main(String[] args) {
        PathSumIII solution = new PathSumIII();

//                 10
//                /  \
//               5   -3
//               / \    \
//              3   2   11
//             / \
//            3  -2
//                /
//               1
        // 构造二叉树

//        TreeNode root = new TreeNode(10);
//        root.left = new TreeNode(5);
//        root.right = new TreeNode(-3);
//        root.left.left = new TreeNode(3);
//        root.left.right = new TreeNode(2);
//        root.right.right = new TreeNode(11);
//        root.left.left.left = new TreeNode(3);
//        root.left.left.right = new TreeNode(-2);
//        root.left.right.right = new TreeNode(1);
//        int targetSum = 8;

//        [1000000000,1000000000,null,294967296,null,1000000000,null,1000000000,null,1000000000]

        TreeNode root = new TreeNode(1000000000);
        root.left = new TreeNode(1000000000);

        root.left.left = new TreeNode(294967296);
        root.left.left.left = new TreeNode(1000000000);
        root.left.left.left.left = new TreeNode(1000000000);
        root.left.left.left.left.left = new TreeNode(1000000000);
        int targetSum = 0;
        System.out.println(solution.pathSum(root, targetSum)); // 输出 3
    }
}

室间空间复杂度

  • 时间复杂度:O(n^2),其中n是二叉树中的节点数,每个节点需要遍历一次,并且需要额外的时间计算从当前节点开始的路径数量。
  • 空间复杂度:O(n),递归调用栈的深度为二叉树的高度。

标签:right,TreeNode,root,targetSum,二叉树,new,437,III,left
From: https://blog.csdn.net/FLGBgo/article/details/137225978

相关文章

  • 2673. 使二叉树所有路径值相等的最小代价
    思路先看3节点的子树,想要路径值相同,只能修改叶子节点的值,如上图只能2去+1操作。核心思想:那么对于任意左右孩子节点,想要从根节点下来的路径相同,只能修改孩子节点。所以我们只需要从下至上记录叶子节点到当前节点的路径值,然后计算当前节点和右节点的差值。详细看灵神树上贪心......
  • [蓝桥杯 2019 省赛 AB] 完全二叉树的权值
    #[蓝桥杯2019省AB]完全二叉树的权值##题目描述给定一棵包含$N$个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是$A_1,A_2,\cdotsA_N$,如下图所示:现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有......
  • 【前端面试3+1】06继承方式及优缺点、缓存策略、url输入到渲染全过程、【二叉树中序遍
    一、继承有哪些方式?以及优缺点        继承的方式包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承和组合式继承。1.原型链继承:实现方式:将子类的原型指向父类的实例来实现继承。优点:简单易懂,代码量少。缺点:存在引用类型共享的问题。functionPare......
  • 2024.2.7力扣每日一题——二叉树的堂兄弟节点2
    2024.2.7题目来源我的题解方法一哈希表+层序遍历(自己的想法,硬在每一层去算)方法二广度优先遍历(官方题解,在上一层求下一层)题目来源力扣每日一题;题序:2461我的题解方法一哈希表+层序遍历(自己的想法,硬在每一层去算)使用两个哈希表分别映射parent<子节点,父节点>,c......
  • 2024.2.8力扣每日一题——二叉树的堂兄弟节点
    2024.2.8题目来源我的题解方法一层序遍历方法二深度优先遍历题目来源力扣每日一题;题序:993我的题解方法一层序遍历使用层序遍历,先判断x或y是否是根节点,若是则x和y必然不可能是堂兄弟节点。每次遍历当前层时判断下一层是否出现x和y,若x和y分别出现在该节点的......
  • 【每周例题】力扣 C++ 二叉树的最小深度
    二叉树的最小深度题目二叉树的最小深度题目分析1.首先我们可以处理最小深度为0与最小深度为1的情况:最小深度为0:头结点为空;root==nullptr最小深度为1:root->left==nullptr&&root->right==nullptr2.接下来分为左右子树处理,我们可以用递归来计算最小深度3.最后比较左......
  • LeetCodeHot100 二叉树 94. 二叉树的中序遍历 104. 二叉树的最大深度 101. 对称二
    94.二叉树的中序遍历https://leetcode.cn/problems/binary-tree-inorder-traversal/description/?envType=study-plan-v2&envId=top-100-liked//递归//List<Integer>resList;//publicList<Integer>inorderTraversal(TreeNoderoot){//re......
  • L2-011 玩转二叉树
    和L2-006是一样的。正常建树,只是在BFS的时候先放右儿子。L2-006树的遍历https://www.cnblogs.com/chengyiyuki/p/18106375代码:#include<bits/stdc++.h>usingnamespacestd;constintN=40;intpre[N],in[N];intL[N],R[N];intbuild(intal,intar,intbl,int......
  • LC 104.二叉树的最大深度
    104.二叉树的最大深度给定一个二叉树root,返回其最大深度。二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。示例1:输入:root=[3,9,20,null,null,15,7]输出:3示例2:输入:root=[1,null,2]输出:2提示:树中节点的数量在......
  • 【数据结构】树与二叉树
    树与二叉树目录树与二叉树树二叉树二叉树的定义二叉树的性质二叉树--存储结构二叉树的顺序存储表示二叉树的链式存储表示二叉链表三叉链表双亲数组遍历二叉树先(根)序的遍历算法中(根)序的遍历算法后(根)序的遍历算法遍历二叉树——相关结论应用二叉树存放表达式求二叉树的......