437 路径总和 III

题目描述:
给定一个二叉树,它的每个结点都存放着一个整数值。
找出路径和等于给定数值的路径总数。
路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

示例:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
在这里插入图片描述
返回 3。和等于 8 的路径有:

  1. 5 -> 3
  2. 5 -> 2 -> 1
  3. -3 -> 11

方法1:使用两个递归
主要思路:
(1)使用两个递归,第一个递归用于统计以各个当前结点为根节点,使用初始值sum,来统计各个子树的路径数量;
(2)第二个递归用于统计给定的子树下,统计各个子树的满足要求的路径所使用的递归;

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int helper(TreeNode* root,int sum){
    	//终止条件
        if(root==NULL)
            return 0;
        sum-=root->val;
        int res=sum==0?1:0;//满足要求的一条部分路径
        return res+helper(root->left,sum)+helper(root->right,sum);//接着递归统计
    }
	//递归函数1
    int pathSum(TreeNode* root, int sum) {
        if(root==NULL)
            return 0;
        int result=helper(root,sum);//统计当前结点下新的树的满足要求的路径的数量
        //以左右结点为新根节点,递归重新统计各个可能的作为子树的结果
        int l_num=pathSum(root->left,sum);
        int r_num=pathSum(root->right,sum);
        return result+l_num+r_num;//将三个结果返回
    }
};

方法2:递归,回溯,前缀和
主要思路:
(1)前缀和是统计到当前结点时,之前的路径中出现的所有值之和(和积分图像有点像),这样,通过当前的前缀和减去之前的某个位置的前缀和,就能够得到之前位置到当前位置之间的所有元素之和;
(2)利用前缀和的概念,可以将路径上的各个结点出的前缀和统计起来,使用unordered_map进行存储,统计某个前缀和的出现次数;
(3)然后,使用当前前缀和减去需要获得路径和sum,得到的值若是在unordered_map中出现过,则说明存在路径,加上相应的路径数量,若是没有,则说明没有组成需要的路径,然后将当前前缀和加入到unordered_map中;
(4)由于路径时递归的,且存储的是当前的路径,故需要进行回溯,去除要成为“之前路径“中的结点;

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

    void helper(TreeNode* root,int& sum,unordered_map<int,int>& mp,int& count,int step){
        if(root==NULL)//终止
            return;
        step+=root->val;//当前前缀和
        if(mp.count(step-sum))//若减去sum后的前缀存在,则说明可以存在符合要求的路径
            count+=mp[step-sum];
        ++mp[step];//将当前前缀和加入到结果中
        //递归
        helper(root->left,sum,mp,count,step);
        helper(root->right,sum,mp,count,step);
        //回溯
        --mp[step];
        if(mp[step]==0) 
            mp.erase(step);
    }

    int pathSum(TreeNode* root, int sum) {
        unordered_map<int,int>mp;//存储前缀和
        mp[0]=1;//初始值
        int count=0;//统计满足要求的路径的数量
        int step=0;//统计当前路径和,名字没取好
        helper(root,sum,mp,count,step);
        return count;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值