【JZ84 二叉树中和为某一值的路径(三)】

描述

给定一个二叉树root和一个整数值 sum ,求该树有多少路径的的节点值之和等于 sum 。

  1. 该题路径定义不需要从根节点开始,也不需要在叶子节点结束,但是一定是从父亲节点往下到孩子节点
  2. 总节点数目为n
  3. 保证最后返回的路径个数在整形范围内(即路径个数小于231-1)

数据范围:

0 <= n <= 1000

−109 <= 节点值 <= 109

假如二叉树root为{1,2,3,4,5,4,3,#,#,-1},sum=6,那么总共如下所示,有3条路径符合要求

在这里插入图片描述

示例1

输入:{1,2,3,4,5,4,3,#,#,-1},6

返回值:3

说明:如图所示,有3条路径符合      

示例2

输入:{0,1},1

返回值:2

示例3

输入:{1,#,2,#,3},3

返回值:2

方法一:两次dfs

具体做法:

可以使用两次 dfs 解决,第一次 dfs 遍历二叉树每个结点,每个结点都作为一次根结点,第二次dfs遍历以每个结点为根的子树,查找该子树是否有路径和等于目标值的。

代码

class Solution {
public:
    int res = 0;
    void dfs(TreeNode* root, int sum){ //dfs查询以某结点为根的路径数
        if(root == NULL)
            return;
        if(sum == root->val) //符合目标值
            res++;
        dfs(root->left, sum - root->val); //进入子节点继续找
        dfs(root->right, sum - root->val);
    }
    int FindPath(TreeNode* root, int sum) { //dfs 以每个结点作为根查询路径
        if(root == NULL) //为空则返回
            return res;
        dfs(root, sum); //查询以某结点为根的路径数
        FindPath(root->left, sum); //以其子结点为新根
        FindPath(root->right, sum);
        return res;
    }
};

运行时间:8ms
超过25.31% 用C++提交的代码
占用内存:520KB
超过60.72%用C++提交的代码
时间复杂度:O(n2),其中 n 为二叉树的结点数,两层 dfs 嵌套递归
空间复杂度:O(n),每层 dfs 最深递归栈都只有 n

方法二:一次dfs+哈希表

具体做法:

两次dfs有些浪费,可以一次dfs解决。在进入以某个结点为根的子树中,向其中添加到该节点为止的路径和进入哈希表中,相当于每次分枝下都有前面各种路径和,相当于我只要查找哈希表就可以找到从中间截断的路径,而遍历完这个分枝后依次删除这个分枝在哈希表中记录的路径和,避免影响别的分枝,只有公共分枝的路径和才会一直记录在哈希表中。

在这里插入图片描述
代码

class Solution {
public:
    unordered_map<int, int> mp; //记录路径和及条数
    int dfs(TreeNode* root, int sum, int last){ //last为到上一层为止的累加和
        if(root == NULL) //空结点直接返回
            return 0;
        int res = 0;
        int temp = root->val + last; //到目前结点为止的累加和
        if(mp.find(temp - sum) != mp.end())  //如果该累加和减去sum在哈希表中出现过,相当于减去前面的分支
            res += mp[temp - sum]; //加上有的路径数
        mp[temp]++; //增加该次路径和
        res += dfs(root->left, sum, temp); //进入子结点
        res += dfs(root->right, sum, temp);
        mp[temp]--; //回退该路径和,因为别的树枝不需要这边存的路径和
        return res;
    }
    int FindPath(TreeNode* root, int sum) {
        mp[0] = 1; //路径和为0的有1条
        return dfs(root, sum, 0);
    }
};

运行时间:4ms
超过88.66% 用C++提交的代码
占用内存:524KB
超过54.51%用C++提交的代码
时间复杂度: O(n),其中nnn为二叉树的结点数,一次 dfs
空间复杂度: O(n),哈希表大小及递归栈最大为 n

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千北@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值