leetcode面试题 04.12. 求和路径(dfs)

本文介绍了一种算法,用于查找二叉树中所有节点数值总和等于给定值的路径数量。通过递归和前缀和的方法,文章详细解释了如何高效地解决这一问题,并提供了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一棵二叉树,其中每个节点都含有一个整数数值(该值或正或负)。设计一个算法,打印节点数值总和等于某个给定值的所有路径的数量。注意,路径不一定非得从二叉树的根节点或叶节点开始或结束,但是其方向必须向下(只能从父节点指向子节点方向)。

示例:
给定如下二叉树,以及目标和 sum = 225
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1
返回:

3
解释:和为 22 的路径有:[5,4,11,2], [5,8,4,5], [4,11,7]

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    int tar, cnt = 0;

    public int pathSum(TreeNode root, int sum) {
        tar = sum;
        Sum(root, 0, new LinkedList<>());
        return cnt;
    }

    public void Sum(TreeNode root, int sum, LinkedList<Integer> res) {//dfs
        if (root == null) return;
        res.add(root.val);
        cnt += um(res);
        Sum(root.left, sum + root.val, res);
        Sum(root.right, sum + root.val, res);
        res.removeLast();
    }

    public int um(LinkedList<Integer> res) {//找当前数组符合的连续子数组
        int temp = 0, r = 0;
        for (int i = res.size() - 1; i >= 0; i--) {
            r += res.get(i);
            if (r == tar) temp++;
        }
        return temp;
    }
}

递归+前缀和+回溯代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    int tar;
    public int pathSum(TreeNode root, int sum) {
        tar = sum;
        HashMap<Integer,Integer> map=new HashMap<>();
        map.put(0,1);//节点本身也算路径
        return helper(root, 0,map);
    }
    public int helper(TreeNode root, int sum,  HashMap<Integer,Integer> map) {

        if (root == null) return 0;
        int cnt=0;
        int res=sum+root.val;
        cnt +=map.getOrDefault(res-tar,0);//符合的前缀和出现的次数就是路径的数量
        map.put(res,map.getOrDefault(res,0)+1);
        if(root.left!=null) cnt+=helper(root.left, res, map);
        if(root.right!=null) cnt+=helper(root.right, res, map);
        map.put(res,map.get(res)-1);//回溯
        return cnt;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值