【二叉树+前缀哈希】力扣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的数量。

相关推荐
一直学习永不止步3 分钟前
LeetCode题练习与总结:赎金信--383
java·数据结构·算法·leetcode·字符串·哈希表·计数
小刘|34 分钟前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
jjyangyou39 分钟前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
van叶~1 小时前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
简简单单做算法1 小时前
基于Retinex算法的图像去雾matlab仿真
算法·matlab·图像去雾·retinex
云卓SKYDROID1 小时前
除草机器人算法以及技术详解!
算法·机器人·科普·高科技·云卓科技·算法技术
半盏茶香2 小时前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏
徐子童2 小时前
双指针算法习题解答
算法
想要打 Acm 的小周同学呀2 小时前
LRU缓存算法
java·算法·缓存
劲夫学编程3 小时前
leetcode:杨辉三角
算法·leetcode·职场和发展