面试算法50:向下的路径节点值之和

题目

给定一棵二叉树和一个值sum,求二叉树中节点值之和等于sum的路径的数目。路径的定义为二叉树中顺着指向子节点的指针向下移动所经过的节点,但不一定从根节点开始,也不一定到叶节点结束。例如,在如图8.5所示中的二叉树中有两条路径的节点值之和等于8,其中,第1条路径从节点5开始经过节点2到达节点1,第2条路径从节点2开始到节点6。

分析

虽然路径不一定从根节点开始,但仍然可以求得从根节点开始到达当前遍历节点的路径所经过的节点值之和。

如果在路径上移动时把所有累加的节点值之和都保存下来,然后移动的过程中求差值,就容易知道是否存在从任意节点出发的值为给定sum的路径。

有了前面的经验,就可以采用二叉树深度优先搜索来解决与路径相关的问题。当遍历到一个节点时,先累加从根节点开始的路径上的节点值之和,再计算到它的左右子节点的路径的节点值之和。这就是典型的前序遍历的顺序。

java 复制代码
public class Test {
    public static void main(String[] args) {
        TreeNode node5 = new TreeNode(5);
        TreeNode node2 = new TreeNode(2);
        TreeNode node4 = new TreeNode(4);
        TreeNode node1 = new TreeNode(1);
        TreeNode node6 = new TreeNode(6);
        TreeNode node3 = new TreeNode(3);
        TreeNode node7 = new TreeNode(7);

        node5.left = node2;
        node5.right = node4;
        node2.left = node1;
        node2.right = node6;
        node4.left = node3;
        node4.right = node7;

        int result = pathSum(node5, 8);
        System.out.println(result);
    }

    public static int pathSum(TreeNode root, int sum) {
        Map<Integer, Integer> map = new HashMap<>();
        map.put(0, 1);// 节点和为0的路径有一个(空路径)

        // path: 遍历节点的路径和
        return dfs(root, sum, map, 0);
    }

    private static int dfs(TreeNode root, int sum, Map<Integer, Integer> map, int path) {
        if (root == null) {
            return 0;
        }

        // 前序遍历
        path += root.val;
        int count = map.getOrDefault(path - sum, 0);// 深度优先遍历,如果以前存在这个差值,那么和当前路径一定是以前路径的延伸
        map.put(path, map.getOrDefault(path, 0) + 1);

        count += dfs(root.left, sum, map, path);
        count += dfs(root.right, sum, map, path);

        // 当前这个节点遍历完成,重回当前节点的父节点继续遍历。
        map.put(path, map.get(path) - 1);

        return count;
    }
}
相关推荐
q_30238195567 分钟前
破局路侧感知困境:毫米波雷达+相机融合算法如何重塑智能交通
数码相机·算法
Robert--cao7 分钟前
人机交互(如 VR 手柄追踪、光标移动、手势识别)的滤波算法
人工智能·算法·人机交互·vr·滤波器
云青山水林9 分钟前
算法竞赛从入门到跳楼(ACM-XCPC、蓝桥杯软件赛等)
c++·算法·蓝桥杯
LYFlied12 分钟前
【每日算法】LeetCode138. 随机链表的复制
数据结构·算法·leetcode·链表
zore_c14 分钟前
【C语言手撕算法】LeetCode-142. 环形链表 II(C语言)
c语言·数据结构·算法·leetcode·链表·推荐算法
yaoh.wang8 小时前
力扣(LeetCode) 13: 罗马数字转整数 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
T1ssy8 小时前
布隆过滤器:用概率换空间的奇妙数据结构
算法·哈希算法
hetao17338379 小时前
2025-12-12~14 hetao1733837的刷题笔记
数据结构·c++·笔记·算法
鲨莎分不晴10 小时前
强化学习第五课 —— A2C & A3C:并行化是如何杀死经验回放
网络·算法·机器学习
搞科研的小刘选手11 小时前
【ISSN/ISBN双刊号】第三届电力电子与人工智能国际学术会议(PEAI 2026)
图像处理·人工智能·算法·电力电子·学术会议