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

路径总和 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),递归调用栈的深度为二叉树的高度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值