【二叉树+前缀哈希】力扣437. 路径总和 III

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

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

示例 1:

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8

输出:3

解释:和等于 8 的路径有 3 条,如图所示。

示例 2:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22

输出:3

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int pathSum(TreeNode* root, int targetSum) {
        int ans = 0;
        unordered_map<long long, int> cnt = {{0,1}};
        auto dfs = [&](auto && dfs, TreeNode *node, long long s){
            if(node == nullptr){
                return;
            }
            s += node -> val;
            ans += cnt.contains(s - targetSum) ? cnt[s - targetSum] : 0;
            cnt[s]++;
            dfs(dfs, node->left, s);
            dfs(dfs, node->right, s);
            cnt[s]--;
        };
        dfs(dfs, root, 0);
        return ans;
    }
};

前缀+哈希的前置知识(力扣560和力扣930),然后加入了树的运算。

cpp 复制代码
auto dfs = [&](auto && dfs, TreeNode *node, long long s){
            if(node == nullptr){

允许 lambda 表达式访问并修改其外部作用域的所有变量。比如 ans 和 cnt 都是在 lambda 表达式之外定义的,通过 [&] 捕获,lambda 可以直接对它们进行操作。

cpp 复制代码
s += node -> val;

s是前缀和。

cpp 复制代码
ans += cnt.contains(s - targetSum) ? cnt[s - targetSum] : 0;

ans用来统计和为targetSum的个数。

cpp 复制代码
cnt[s]++;

记录当前节点的前缀和在哈希表中数目+1,供接下来的运算。

cpp 复制代码
dfs(dfs, node->left, s);
dfs(dfs, node->right, s);

按深度优先搜索遍历树。

cpp 复制代码
cnt[s]--;

恢复现场,这一步很重要,例如当运算完左子树返回到父节点的时候,要开始运算右子树,由于左子树和右子树在计算路径的时候并没有关联,所以需要恢复左子树前缀和对应在哈希表中的数量,避免影响计算右子树路径和为targetSum的数量。

相关推荐
aigcapi3 小时前
RAG 系统的黑盒测试:从算法对齐视角解析 GEO 优化的技术指标体系
大数据·人工智能·算法
柯慕灵4 小时前
7大推荐系统/算法框架对比
算法·推荐算法
adam-liu4 小时前
Fun Audio Chat 论文+项目调研
算法·语音端到端·fun-audio-chat
栀秋6665 小时前
你会先找行还是直接拍平?两种二分策略你Pick哪个?
前端·javascript·算法
如果你想拥有什么先让自己配得上拥有5 小时前
数学思想和数学思维分别都有什么?
线性代数·算法·机器学习
长安er5 小时前
LeetCode136/169/75/31/287 算法技巧题核心笔记
数据结构·算法·leetcode·链表·双指针
MarkHD5 小时前
智能体在车联网中的应用:第29天 多智能体完全合作场景的核心算法:从CTDE思想到VDN与MADDPG的深度解析
算法
wanzhong23336 小时前
CUDA学习5-矩阵乘法(共享内存版)
深度学习·学习·算法·cuda·高性能计算
fufu03116 小时前
Linux环境下的C语言编程(四十八)
数据结构·算法·排序算法
Yingye Zhu(HPXXZYY)7 小时前
Solution to Luogu P6340
算法